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 * @unimplemented 638 */ 639 NTSTATUS NTAPI 640 RtlUnicodeToOemN(OUT PCHAR OemString, 641 IN ULONG OemSize, 642 OUT PULONG ResultSize OPTIONAL, 643 IN PCWCH UnicodeString, 644 IN ULONG UnicodeSize) 645 { 646 ULONG Size = 0; 647 ULONG i; 648 649 PAGED_CODE_RTL(); 650 651 if (!NlsMbOemCodePageTag) 652 { 653 /* single-byte code page */ 654 if (UnicodeSize > (OemSize * sizeof(WCHAR))) 655 Size = OemSize; 656 else 657 Size = UnicodeSize / sizeof(WCHAR); 658 659 if (ResultSize) 660 *ResultSize = Size; 661 662 for (i = 0; i < Size; i++) 663 { 664 *OemString = NlsUnicodeToOemTable[*UnicodeString]; 665 OemString++; 666 UnicodeString++; 667 } 668 } 669 else 670 { 671 /* multi-byte code page */ 672 /* FIXME */ 673 674 USHORT WideChar; 675 USHORT OemChar; 676 677 for (i = OemSize, Size = UnicodeSize / sizeof(WCHAR); i && Size; i--, Size--) 678 { 679 WideChar = *UnicodeString++; 680 681 if (WideChar < 0x80) 682 { 683 *OemString++ = LOBYTE(WideChar); 684 continue; 685 } 686 687 OemChar = NlsUnicodeToMbOemTable[WideChar]; 688 689 if (!HIBYTE(OemChar)) 690 { 691 *OemString++ = LOBYTE(OemChar); 692 continue; 693 } 694 695 if (i >= 2) 696 { 697 *OemString++ = HIBYTE(OemChar); 698 *OemString++ = LOBYTE(OemChar); 699 i--; 700 } 701 else break; 702 } 703 704 if (ResultSize) 705 *ResultSize = OemSize - i; 706 } 707 708 return STATUS_SUCCESS; 709 } 710 711 /* 712 * @implemented 713 */ 714 WCHAR NTAPI 715 RtlpUpcaseUnicodeChar(IN WCHAR Source) 716 { 717 USHORT Offset; 718 719 if (Source < 'a') 720 return Source; 721 722 if (Source <= 'z') 723 return (Source - ('a' - 'A')); 724 725 Offset = ((USHORT)Source >> 8) & 0xFF; 726 Offset = NlsUnicodeUpcaseTable[Offset]; 727 728 Offset += ((USHORT)Source >> 4) & 0xF; 729 Offset = NlsUnicodeUpcaseTable[Offset]; 730 731 Offset += ((USHORT)Source & 0xF); 732 Offset = NlsUnicodeUpcaseTable[Offset]; 733 734 return Source + (SHORT)Offset; 735 } 736 737 /* 738 * @implemented 739 */ 740 WCHAR NTAPI 741 RtlUpcaseUnicodeChar(IN WCHAR Source) 742 { 743 PAGED_CODE_RTL(); 744 745 return RtlpUpcaseUnicodeChar(Source); 746 } 747 748 /* 749 * @implemented 750 */ 751 NTSTATUS NTAPI 752 RtlUpcaseUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP, 753 OUT PCHAR CustomString, 754 IN ULONG CustomSize, 755 OUT PULONG ResultSize OPTIONAL, 756 IN PWCHAR UnicodeString, 757 IN ULONG UnicodeSize) 758 { 759 WCHAR UpcaseChar; 760 ULONG Size = 0; 761 ULONG i; 762 763 PAGED_CODE_RTL(); 764 765 if (!CustomCP->DBCSCodePage) 766 { 767 /* single-byte code page */ 768 if (UnicodeSize > (CustomSize * sizeof(WCHAR))) 769 Size = CustomSize; 770 else 771 Size = UnicodeSize / sizeof(WCHAR); 772 773 if (ResultSize) 774 *ResultSize = Size; 775 776 for (i = 0; i < Size; i++) 777 { 778 UpcaseChar = RtlpUpcaseUnicodeChar(*UnicodeString); 779 *CustomString = ((PCHAR)CustomCP->WideCharTable)[UpcaseChar]; 780 ++CustomString; 781 ++UnicodeString; 782 } 783 } 784 else 785 { 786 /* multi-byte code page */ 787 /* FIXME */ 788 ASSERT(FALSE); 789 } 790 791 return STATUS_SUCCESS; 792 } 793 794 /* 795 * @unimplemented 796 */ 797 NTSTATUS NTAPI 798 RtlUpcaseUnicodeToMultiByteN(OUT PCHAR MbString, 799 IN ULONG MbSize, 800 OUT PULONG ResultSize OPTIONAL, 801 IN PCWCH UnicodeString, 802 IN ULONG UnicodeSize) 803 { 804 WCHAR UpcaseChar; 805 ULONG Size = 0; 806 ULONG i; 807 808 PAGED_CODE_RTL(); 809 810 if (!NlsMbCodePageTag) 811 { 812 /* single-byte code page */ 813 if (UnicodeSize > (MbSize * sizeof(WCHAR))) 814 Size = MbSize; 815 else 816 Size = UnicodeSize / sizeof(WCHAR); 817 818 if (ResultSize) 819 *ResultSize = Size; 820 821 for (i = 0; i < Size; i++) 822 { 823 UpcaseChar = RtlpUpcaseUnicodeChar(*UnicodeString); 824 *MbString = NlsUnicodeToAnsiTable[UpcaseChar]; 825 MbString++; 826 UnicodeString++; 827 } 828 } 829 else 830 { 831 /* multi-byte code page */ 832 /* FIXME */ 833 ASSERT(FALSE); 834 } 835 836 return STATUS_SUCCESS; 837 } 838 839 /* 840 * @unimplemented 841 */ 842 NTSTATUS NTAPI 843 RtlUpcaseUnicodeToOemN(OUT PCHAR OemString, 844 IN ULONG OemSize, 845 OUT PULONG ResultSize OPTIONAL, 846 IN PCWCH UnicodeString, 847 IN ULONG UnicodeSize) 848 { 849 WCHAR UpcaseChar; 850 ULONG Size = 0; 851 ULONG i; 852 853 PAGED_CODE_RTL(); 854 855 ASSERT(NlsUnicodeToOemTable != NULL); 856 857 if (!NlsMbOemCodePageTag) 858 { 859 /* single-byte code page */ 860 if (UnicodeSize > (OemSize * sizeof(WCHAR))) 861 Size = OemSize; 862 else 863 Size = UnicodeSize / sizeof(WCHAR); 864 865 if (ResultSize) 866 *ResultSize = Size; 867 868 for (i = 0; i < Size; i++) 869 { 870 UpcaseChar = RtlpUpcaseUnicodeChar(*UnicodeString); 871 *OemString = NlsUnicodeToOemTable[UpcaseChar]; 872 OemString++; 873 UnicodeString++; 874 } 875 } 876 else 877 { 878 /* multi-byte code page */ 879 /* FIXME */ 880 881 USHORT WideChar; 882 USHORT OemChar; 883 884 for (i = OemSize, Size = UnicodeSize / sizeof(WCHAR); i && Size; i--, Size--) 885 { 886 WideChar = RtlpUpcaseUnicodeChar(*UnicodeString++); 887 888 if (WideChar < 0x80) 889 { 890 *OemString++ = LOBYTE(WideChar); 891 continue; 892 } 893 894 OemChar = NlsUnicodeToMbOemTable[WideChar]; 895 896 if (!HIBYTE(OemChar)) 897 { 898 *OemString++ = LOBYTE(OemChar); 899 continue; 900 } 901 902 if (i >= 2) 903 { 904 *OemString++ = HIBYTE(OemChar); 905 *OemString++ = LOBYTE(OemChar); 906 i--; 907 } 908 else break; 909 } 910 911 if (ResultSize) 912 *ResultSize = OemSize - i; 913 } 914 915 return STATUS_SUCCESS; 916 } 917 918 /* 919 * @unimplemented 920 */ 921 CHAR NTAPI 922 RtlUpperChar(IN CHAR Source) 923 { 924 WCHAR Unicode; 925 CHAR Destination; 926 927 PAGED_CODE_RTL(); 928 929 /* Check for simple ANSI case */ 930 if (Source <= 'z') 931 { 932 /* Check for simple downcase a-z case */ 933 if (Source >= 'a') 934 { 935 /* Just XOR with the difference */ 936 return Source ^ ('a' - 'A'); 937 } 938 else 939 { 940 /* Otherwise return the same char, it's already upcase */ 941 return Source; 942 } 943 } 944 else 945 { 946 if (!NlsMbCodePageTag) 947 { 948 /* single-byte code page */ 949 950 /* ansi->unicode */ 951 Unicode = NlsAnsiToUnicodeTable[(UCHAR)Source]; 952 953 /* upcase conversion */ 954 Unicode = RtlpUpcaseUnicodeChar (Unicode); 955 956 /* unicode -> ansi */ 957 Destination = NlsUnicodeToAnsiTable[(USHORT)Unicode]; 958 } 959 else 960 { 961 /* multi-byte code page */ 962 /* FIXME */ 963 Destination = Source; 964 } 965 } 966 967 return Destination; 968 } 969 970 /* EOF */ 971