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 UnicodeString[i] = NlsAnsiToUnicodeTable[(UCHAR)MbString[i]]; 255 } 256 else 257 { 258 /* multi-byte code page */ 259 /* FIXME */ 260 261 UCHAR Char; 262 USHORT LeadByteInfo; 263 PCSTR MbEnd = MbString + MbSize; 264 265 for (i = 0; i < UnicodeSize / sizeof(WCHAR) && MbString < MbEnd; i++) 266 { 267 Char = *(PUCHAR)MbString++; 268 269 if (Char < 0x80) 270 { 271 *UnicodeString++ = Char; 272 continue; 273 } 274 275 LeadByteInfo = NlsLeadByteInfo[Char]; 276 277 if (!LeadByteInfo) 278 { 279 *UnicodeString++ = NlsAnsiToUnicodeTable[Char]; 280 continue; 281 } 282 283 if (MbString < MbEnd) 284 *UnicodeString++ = NlsLeadByteInfo[LeadByteInfo + *(PUCHAR)MbString++]; 285 } 286 287 if (ResultSize) 288 *ResultSize = i * sizeof(WCHAR); 289 } 290 291 return STATUS_SUCCESS; 292 } 293 294 /* 295 * @unimplemented 296 */ 297 NTSTATUS 298 NTAPI 299 RtlConsoleMultiByteToUnicodeN(OUT PWCHAR UnicodeString, 300 IN ULONG UnicodeSize, 301 OUT PULONG ResultSize, 302 IN PCSTR MbString, 303 IN ULONG MbSize, 304 OUT PULONG Unknown) 305 { 306 PAGED_CODE_RTL(); 307 308 UNIMPLEMENTED; 309 DPRINT1("RtlConsoleMultiByteToUnicodeN calling RtlMultiByteToUnicodeN\n"); 310 *Unknown = 1; 311 return RtlMultiByteToUnicodeN(UnicodeString, 312 UnicodeSize, 313 ResultSize, 314 MbString, 315 MbSize); 316 } 317 318 /* 319 * @implemented 320 */ 321 NTSTATUS 322 NTAPI 323 RtlMultiByteToUnicodeSize(OUT PULONG UnicodeSize, 324 IN PCSTR MbString, 325 IN ULONG MbSize) 326 { 327 ULONG Length = 0; 328 329 PAGED_CODE_RTL(); 330 331 if (!NlsMbCodePageTag) 332 { 333 /* single-byte code page */ 334 *UnicodeSize = MbSize * sizeof (WCHAR); 335 } 336 else 337 { 338 /* multi-byte code page */ 339 /* FIXME */ 340 341 while (MbSize--) 342 { 343 UCHAR Char = *(PUCHAR)MbString++; 344 345 if (Char >= 0x80 && NlsLeadByteInfo[Char]) 346 { 347 if (MbSize) 348 { 349 /* Move on */ 350 MbSize--; 351 MbString++; 352 } 353 } 354 355 /* Increase returned size */ 356 Length++; 357 } 358 359 /* Return final size */ 360 *UnicodeSize = Length * sizeof(WCHAR); 361 } 362 363 /* Success */ 364 return STATUS_SUCCESS; 365 } 366 367 /* 368 * @unimplemented 369 */ 370 NTSTATUS NTAPI 371 RtlOemToUnicodeN(OUT PWCHAR UnicodeString, 372 IN ULONG UnicodeSize, 373 OUT PULONG ResultSize OPTIONAL, 374 IN PCCH OemString, 375 IN ULONG OemSize) 376 { 377 ULONG Size = 0; 378 ULONG i; 379 380 PAGED_CODE_RTL(); 381 382 if (!NlsMbOemCodePageTag) 383 { 384 /* single-byte code page */ 385 if (OemSize > (UnicodeSize / sizeof(WCHAR))) 386 Size = UnicodeSize / sizeof(WCHAR); 387 else 388 Size = OemSize; 389 390 if (ResultSize) 391 *ResultSize = Size * sizeof(WCHAR); 392 393 for (i = 0; i < Size; i++) 394 { 395 *UnicodeString = NlsOemToUnicodeTable[(UCHAR)*OemString]; 396 UnicodeString++; 397 OemString++; 398 } 399 } 400 else 401 { 402 /* multi-byte code page */ 403 /* FIXME */ 404 405 UCHAR Char; 406 USHORT OemLeadByteInfo; 407 PCCH OemEnd = OemString + OemSize; 408 409 for (i = 0; i < UnicodeSize / sizeof(WCHAR) && OemString < OemEnd; i++) 410 { 411 Char = *(PUCHAR)OemString++; 412 413 if (Char < 0x80) 414 { 415 *UnicodeString++ = Char; 416 continue; 417 } 418 419 OemLeadByteInfo = NlsOemLeadByteInfo[Char]; 420 421 if (!OemLeadByteInfo) 422 { 423 *UnicodeString++ = NlsOemToUnicodeTable[Char]; 424 continue; 425 } 426 427 if (OemString < OemEnd) 428 *UnicodeString++ = 429 NlsOemLeadByteInfo[OemLeadByteInfo + *(PUCHAR)OemString++]; 430 } 431 432 if (ResultSize) 433 *ResultSize = i * sizeof(WCHAR); 434 } 435 436 return STATUS_SUCCESS; 437 } 438 439 /* 440 * @implemented 441 */ 442 VOID NTAPI 443 RtlResetRtlTranslations(IN PNLSTABLEINFO NlsTable) 444 { 445 PAGED_CODE_RTL(); 446 447 DPRINT("RtlResetRtlTranslations() called\n"); 448 449 /* Set ANSI data */ 450 NlsAnsiToUnicodeTable = (PUSHORT)NlsTable->AnsiTableInfo.MultiByteTable; 451 NlsUnicodeToAnsiTable = NlsTable->AnsiTableInfo.WideCharTable; 452 NlsUnicodeToMbAnsiTable = (PUSHORT)NlsTable->AnsiTableInfo.WideCharTable; 453 NlsMbCodePageTag = (NlsTable->AnsiTableInfo.DBCSCodePage != 0); 454 NlsLeadByteInfo = NlsTable->AnsiTableInfo.DBCSOffsets; 455 NlsAnsiCodePage = NlsTable->AnsiTableInfo.CodePage; 456 DPRINT("Ansi codepage %hu\n", NlsAnsiCodePage); 457 458 /* Set OEM data */ 459 NlsOemToUnicodeTable = (PUSHORT)NlsTable->OemTableInfo.MultiByteTable; 460 NlsUnicodeToOemTable = NlsTable->OemTableInfo.WideCharTable; 461 NlsUnicodeToMbOemTable = (PUSHORT)NlsTable->OemTableInfo.WideCharTable; 462 NlsMbOemCodePageTag = (NlsTable->OemTableInfo.DBCSCodePage != 0); 463 NlsOemLeadByteInfo = NlsTable->OemTableInfo.DBCSOffsets; 464 NlsOemCodePage = NlsTable->OemTableInfo.CodePage; 465 DPRINT("Oem codepage %hu\n", NlsOemCodePage); 466 467 /* Set Unicode case map data */ 468 NlsUnicodeUpcaseTable = NlsTable->UpperCaseTable; 469 NlsUnicodeLowercaseTable = NlsTable->LowerCaseTable; 470 471 /* set the default characters for RtlpDidUnicodeToOemWork */ 472 NlsOemDefaultChar = NlsTable->OemTableInfo.DefaultChar; 473 NlsUnicodeDefaultChar = NlsTable->OemTableInfo.TransDefaultChar; 474 } 475 476 /* 477 * @unimplemented 478 */ 479 NTSTATUS NTAPI 480 RtlUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP, 481 OUT PCHAR CustomString, 482 IN ULONG CustomSize, 483 OUT PULONG ResultSize OPTIONAL, 484 IN PWCHAR UnicodeString, 485 IN ULONG UnicodeSize) 486 { 487 ULONG Size = 0; 488 ULONG i; 489 490 PAGED_CODE_RTL(); 491 492 if (!CustomCP->DBCSCodePage) 493 { 494 /* single-byte code page */ 495 if (UnicodeSize > (CustomSize * sizeof(WCHAR))) 496 Size = CustomSize; 497 else 498 Size = UnicodeSize / sizeof(WCHAR); 499 500 if (ResultSize) 501 *ResultSize = Size; 502 503 for (i = 0; i < Size; i++) 504 { 505 *CustomString = ((PCHAR)CustomCP->WideCharTable)[*UnicodeString]; 506 CustomString++; 507 UnicodeString++; 508 } 509 } 510 else 511 { 512 /* multi-byte code page */ 513 /* FIXME */ 514 ASSERT(FALSE); 515 } 516 517 return STATUS_SUCCESS; 518 } 519 520 /* 521 * @unimplemented 522 */ 523 NTSTATUS NTAPI 524 RtlUnicodeToMultiByteN(OUT PCHAR MbString, 525 IN ULONG MbSize, 526 OUT PULONG ResultSize OPTIONAL, 527 IN PCWCH UnicodeString, 528 IN ULONG UnicodeSize) 529 { 530 ULONG Size = 0; 531 ULONG i; 532 533 PAGED_CODE_RTL(); 534 535 if (!NlsMbCodePageTag) 536 { 537 /* single-byte code page */ 538 Size = (UnicodeSize > (MbSize * sizeof (WCHAR))) 539 ? MbSize : (UnicodeSize / sizeof (WCHAR)); 540 541 if (ResultSize) 542 *ResultSize = Size; 543 544 for (i = 0; i < Size; i++) 545 { 546 *MbString++ = NlsUnicodeToAnsiTable[*UnicodeString++]; 547 } 548 } 549 else 550 { 551 /* multi-byte code page */ 552 /* FIXME */ 553 554 USHORT WideChar; 555 USHORT MbChar; 556 557 for (i = MbSize, Size = UnicodeSize / sizeof(WCHAR); i && Size; i--, Size--) 558 { 559 WideChar = *UnicodeString++; 560 561 if (WideChar < 0x80) 562 { 563 *MbString++ = LOBYTE(WideChar); 564 continue; 565 } 566 567 MbChar = NlsUnicodeToMbAnsiTable[WideChar]; 568 569 if (!HIBYTE(MbChar)) 570 { 571 *MbString++ = LOBYTE(MbChar); 572 continue; 573 } 574 575 if (i >= 2) 576 { 577 *MbString++ = HIBYTE(MbChar); 578 *MbString++ = LOBYTE(MbChar); 579 i--; 580 } 581 else break; 582 } 583 584 if (ResultSize) 585 *ResultSize = MbSize - i; 586 } 587 588 return STATUS_SUCCESS; 589 } 590 591 /* 592 * @implemented 593 */ 594 NTSTATUS 595 NTAPI 596 RtlUnicodeToMultiByteSize(OUT PULONG MbSize, 597 IN PCWCH UnicodeString, 598 IN ULONG UnicodeSize) 599 { 600 ULONG UnicodeLength = UnicodeSize / sizeof(WCHAR); 601 ULONG MbLength = 0; 602 603 PAGED_CODE_RTL(); 604 605 if (!NlsMbCodePageTag) 606 { 607 /* single-byte code page */ 608 *MbSize = UnicodeLength; 609 } 610 else 611 { 612 /* multi-byte code page */ 613 /* FIXME */ 614 615 while (UnicodeLength--) 616 { 617 USHORT WideChar = *UnicodeString++; 618 619 if (WideChar >= 0x80 && HIBYTE(NlsUnicodeToMbAnsiTable[WideChar])) 620 { 621 MbLength += sizeof(WCHAR); 622 } 623 else 624 { 625 MbLength++; 626 } 627 } 628 629 *MbSize = MbLength; 630 } 631 632 /* Success */ 633 return STATUS_SUCCESS; 634 } 635 636 /* 637 * @implemented 638 */ 639 NTSTATUS 640 NTAPI 641 RtlUnicodeToOemN(OUT PCHAR OemString, 642 IN ULONG OemSize, 643 OUT PULONG ResultSize OPTIONAL, 644 IN PCWCH UnicodeString, 645 IN ULONG UnicodeSize) 646 { 647 ULONG Size = 0; 648 649 PAGED_CODE_RTL(); 650 651 /* Bytes -> chars */ 652 UnicodeSize /= sizeof(WCHAR); 653 654 if (!NlsMbOemCodePageTag) 655 { 656 while (OemSize && UnicodeSize) 657 { 658 OemString[Size] = NlsUnicodeToOemTable[*UnicodeString++]; 659 Size++; 660 OemSize--; 661 UnicodeSize--; 662 } 663 } 664 else 665 { 666 while (OemSize && UnicodeSize) 667 { 668 USHORT OemChar = NlsUnicodeToMbOemTable[*UnicodeString++]; 669 670 if (HIBYTE(OemChar)) 671 { 672 if (OemSize < 2) 673 break; 674 OemString[Size++] = HIBYTE(OemChar); 675 OemSize--; 676 } 677 OemString[Size++] = LOBYTE(OemChar); 678 OemSize--; 679 UnicodeSize--; 680 } 681 } 682 683 if (ResultSize) 684 *ResultSize = Size; 685 686 return UnicodeSize ? STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS; 687 } 688 689 /* 690 * @implemented 691 */ 692 WCHAR NTAPI 693 RtlpUpcaseUnicodeChar(IN WCHAR Source) 694 { 695 USHORT Offset; 696 697 if (Source < 'a') 698 return Source; 699 700 if (Source <= 'z') 701 return (Source - ('a' - 'A')); 702 703 Offset = ((USHORT)Source >> 8) & 0xFF; 704 Offset = NlsUnicodeUpcaseTable[Offset]; 705 706 Offset += ((USHORT)Source >> 4) & 0xF; 707 Offset = NlsUnicodeUpcaseTable[Offset]; 708 709 Offset += ((USHORT)Source & 0xF); 710 Offset = NlsUnicodeUpcaseTable[Offset]; 711 712 return Source + (SHORT)Offset; 713 } 714 715 /* 716 * @implemented 717 */ 718 WCHAR NTAPI 719 RtlUpcaseUnicodeChar(IN WCHAR Source) 720 { 721 PAGED_CODE_RTL(); 722 723 return RtlpUpcaseUnicodeChar(Source); 724 } 725 726 /* 727 * @implemented 728 */ 729 NTSTATUS NTAPI 730 RtlUpcaseUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP, 731 OUT PCHAR CustomString, 732 IN ULONG CustomSize, 733 OUT PULONG ResultSize OPTIONAL, 734 IN PWCHAR UnicodeString, 735 IN ULONG UnicodeSize) 736 { 737 WCHAR UpcaseChar; 738 ULONG Size = 0; 739 ULONG i; 740 741 PAGED_CODE_RTL(); 742 743 if (!CustomCP->DBCSCodePage) 744 { 745 /* single-byte code page */ 746 if (UnicodeSize > (CustomSize * sizeof(WCHAR))) 747 Size = CustomSize; 748 else 749 Size = UnicodeSize / sizeof(WCHAR); 750 751 if (ResultSize) 752 *ResultSize = Size; 753 754 for (i = 0; i < Size; i++) 755 { 756 UpcaseChar = RtlpUpcaseUnicodeChar(*UnicodeString); 757 *CustomString = ((PCHAR)CustomCP->WideCharTable)[UpcaseChar]; 758 ++CustomString; 759 ++UnicodeString; 760 } 761 } 762 else 763 { 764 /* multi-byte code page */ 765 /* FIXME */ 766 ASSERT(FALSE); 767 } 768 769 return STATUS_SUCCESS; 770 } 771 772 /* 773 * @unimplemented 774 */ 775 NTSTATUS NTAPI 776 RtlUpcaseUnicodeToMultiByteN(OUT PCHAR MbString, 777 IN ULONG MbSize, 778 OUT PULONG ResultSize OPTIONAL, 779 IN PCWCH UnicodeString, 780 IN ULONG UnicodeSize) 781 { 782 WCHAR UpcaseChar; 783 ULONG Size = 0; 784 ULONG i; 785 786 PAGED_CODE_RTL(); 787 788 if (!NlsMbCodePageTag) 789 { 790 /* single-byte code page */ 791 if (UnicodeSize > (MbSize * sizeof(WCHAR))) 792 Size = MbSize; 793 else 794 Size = UnicodeSize / sizeof(WCHAR); 795 796 if (ResultSize) 797 *ResultSize = Size; 798 799 for (i = 0; i < Size; i++) 800 { 801 UpcaseChar = RtlpUpcaseUnicodeChar(*UnicodeString); 802 *MbString = NlsUnicodeToAnsiTable[UpcaseChar]; 803 MbString++; 804 UnicodeString++; 805 } 806 } 807 else 808 { 809 /* multi-byte code page */ 810 /* FIXME */ 811 ASSERT(FALSE); 812 } 813 814 return STATUS_SUCCESS; 815 } 816 817 /* 818 * @unimplemented 819 */ 820 NTSTATUS NTAPI 821 RtlUpcaseUnicodeToOemN(OUT PCHAR OemString, 822 IN ULONG OemSize, 823 OUT PULONG ResultSize OPTIONAL, 824 IN PCWCH UnicodeString, 825 IN ULONG UnicodeSize) 826 { 827 WCHAR UpcaseChar; 828 ULONG Size = 0; 829 ULONG i; 830 831 PAGED_CODE_RTL(); 832 833 ASSERT(NlsUnicodeToOemTable != NULL); 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