Initialize pointers to lead byte info tables.
[reactos.git] / reactos / ntoskrnl / rtl / nls.c
1 /* $Id: nls.c,v 1.16 2003/06/17 10:44:16 ekohl Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/rtl/nls.c
6 * PURPOSE: National Language Support (NLS) functions
7 * UPDATE HISTORY:
8 * 20/08/99 Created by Emanuele Aliberti
9 * 10/11/99 Added translation functions.
10 *
11 * TODO:
12 * 1) Add multi-byte translation code.
13 */
14
15 #include <ddk/ntddk.h>
16 #include <internal/mm.h>
17 #include <internal/nls.h>
18
19 #define NDEBUG
20 #include <internal/debug.h>
21
22
23 /* GLOBALS *******************************************************************/
24
25 USHORT NlsAnsiCodePage = 0; /* exported */
26 BOOLEAN NlsMbCodePageTag = FALSE; /* exported */
27 PWCHAR NlsAnsiToUnicodeTable = NULL;
28 PCHAR NlsUnicodeToAnsiTable = NULL;
29 PWCHAR NlsDbcsUnicodeToAnsiTable = NULL;
30 PUSHORT NlsLeadByteInfo = NULL; /* exported */
31
32
33 USHORT NlsOemCodePage = 0;
34 BOOLEAN NlsMbOemCodePageTag = FALSE; /* exported */
35 PWCHAR NlsOemToUnicodeTable = NULL;
36 PCHAR NlsUnicodeToOemTable =NULL;
37 PWCHAR NlsDbcsUnicodeToOemTable = NULL;
38 PUSHORT NlsOemLeadByteInfo = NULL; /* exported */
39
40
41 PUSHORT NlsUnicodeUpcaseTable = NULL;
42 PUSHORT NlsUnicodeLowercaseTable = NULL;
43
44
45 static PUSHORT NlsAnsiCodePageTable = NULL;
46 static ULONG NlsAnsiCodePageTableSize = 0;
47
48 static PUSHORT NlsOemCodePageTable = NULL;
49 static ULONG NlsOemCodePageTableSize = 0;
50
51 static PUSHORT NlsUnicodeCasemapTable = NULL;
52 static ULONG NlsUnicodeCasemapTableSize = 0;
53
54 PVOID NlsSectionObject = NULL;
55 static PVOID NlsSectionBase = NULL;
56 static ULONG NlsSectionViewSize = 0;
57
58 ULONG NlsAnsiTableOffset = 0;
59 ULONG NlsOemTableOffset = 0;
60 ULONG NlsUnicodeTableOffset = 0;
61
62
63 /* FUNCTIONS *****************************************************************/
64
65 VOID
66 RtlpImportAnsiCodePage(PUSHORT TableBase,
67 ULONG Size)
68 {
69 NlsAnsiCodePageTable = TableBase;
70 NlsAnsiCodePageTableSize = Size;
71 }
72
73
74 VOID
75 RtlpImportOemCodePage(PUSHORT TableBase,
76 ULONG Size)
77 {
78 NlsOemCodePageTable = TableBase;
79 NlsOemCodePageTableSize = Size;
80 }
81
82
83 VOID
84 RtlpImportUnicodeCasemap(PUSHORT TableBase,
85 ULONG Size)
86 {
87 NlsUnicodeCasemapTable = TableBase;
88 NlsUnicodeCasemapTableSize = Size;
89 }
90
91
92 VOID
93 RtlpCreateInitialNlsTables(VOID)
94 {
95 NLSTABLEINFO NlsTable;
96
97 if (NlsAnsiCodePageTable == NULL || NlsAnsiCodePageTableSize == 0 ||
98 NlsOemCodePageTable == NULL || NlsOemCodePageTableSize == 0 ||
99 NlsUnicodeCasemapTable == NULL || NlsUnicodeCasemapTableSize == 0)
100 {
101 KeBugCheckEx (0x32, STATUS_UNSUCCESSFUL, 1, 0, 0);
102 }
103
104 RtlInitNlsTables (NlsAnsiCodePageTable,
105 NlsOemCodePageTable,
106 NlsUnicodeCasemapTable,
107 &NlsTable);
108
109 RtlResetRtlTranslations (&NlsTable);
110 }
111
112
113
114
115 VOID
116 RtlpCreateNlsSection(VOID)
117 {
118 NLSTABLEINFO NlsTable;
119 LARGE_INTEGER SectionSize;
120 HANDLE SectionHandle;
121 NTSTATUS Status;
122
123 DPRINT("RtlpCreateNlsSection() called\n");
124
125 NlsSectionViewSize = ROUND_UP(NlsAnsiCodePageTableSize, PAGE_SIZE) +
126 ROUND_UP(NlsOemCodePageTableSize, PAGE_SIZE) +
127 ROUND_UP(NlsUnicodeCasemapTableSize, PAGE_SIZE);
128
129 DPRINT("NlsSectionViewSize %lx\n", NlsSectionViewSize);
130
131 SectionSize.QuadPart = (LONGLONG)NlsSectionViewSize;
132 Status = NtCreateSection(&SectionHandle,
133 SECTION_ALL_ACCESS,
134 NULL,
135 &SectionSize,
136 PAGE_READWRITE,
137 SEC_COMMIT,
138 NULL);
139 if (!NT_SUCCESS(Status))
140 {
141 DPRINT1("NtCreateSection() failed\n");
142 KeBugCheckEx(0x32, Status, 1, 1, 0);
143 }
144
145 Status = ObReferenceObjectByHandle(SectionHandle,
146 SECTION_ALL_ACCESS,
147 MmSectionObjectType,
148 KernelMode,
149 &NlsSectionObject,
150 NULL);
151 NtClose(SectionHandle);
152 if (!NT_SUCCESS(Status))
153 {
154 DPRINT1("ObReferenceObjectByHandle() failed\n");
155 KeBugCheckEx(0x32, Status, 1, 2, 0);
156 }
157
158 Status = MmMapViewInSystemSpace(NlsSectionObject,
159 &NlsSectionBase,
160 &NlsSectionViewSize);
161 NtClose(SectionHandle);
162 if (!NT_SUCCESS(Status))
163 {
164 DPRINT1("MmMapViewInSystemSpace() failed\n");
165 KeBugCheckEx(0x32, Status, 1, 3, 0);
166 }
167
168 DPRINT("NlsSection: Base %p Size %lx\n",
169 NlsSectionBase,
170 NlsSectionViewSize);
171
172 NlsAnsiTableOffset = 0;
173 RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsAnsiTableOffset),
174 NlsAnsiCodePageTable,
175 NlsAnsiCodePageTableSize);
176
177 NlsOemTableOffset = NlsAnsiTableOffset + ROUND_UP(NlsAnsiCodePageTableSize, PAGE_SIZE);
178 RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsOemTableOffset),
179 NlsOemCodePageTable,
180 NlsOemCodePageTableSize);
181
182 NlsUnicodeTableOffset = NlsOemTableOffset + ROUND_UP(NlsOemCodePageTableSize, PAGE_SIZE);
183 RtlCopyMemory((PVOID)((ULONG)NlsSectionBase + NlsUnicodeTableOffset),
184 NlsUnicodeCasemapTable,
185 NlsUnicodeCasemapTableSize);
186
187 RtlInitNlsTables ((PVOID)((ULONG)NlsSectionBase + NlsAnsiTableOffset),
188 (PVOID)((ULONG)NlsSectionBase + NlsOemTableOffset),
189 (PVOID)((ULONG)NlsSectionBase + NlsUnicodeTableOffset),
190 &NlsTable);
191
192 RtlResetRtlTranslations (&NlsTable);
193 }
194
195
196 NTSTATUS STDCALL
197 RtlCustomCPToUnicodeN(IN PCPTABLEINFO CustomCP,
198 PWCHAR UnicodeString,
199 ULONG UnicodeSize,
200 PULONG ResultSize,
201 PCHAR CustomString,
202 ULONG CustomSize)
203 {
204 ULONG Size = 0;
205 ULONG i;
206
207 if (CustomCP->DBCSCodePage == 0)
208 {
209 /* single-byte code page */
210 if (CustomSize > (UnicodeSize / sizeof(WCHAR)))
211 Size = UnicodeSize / sizeof(WCHAR);
212 else
213 Size = CustomSize;
214
215 if (ResultSize != NULL)
216 *ResultSize = Size * sizeof(WCHAR);
217
218 for (i = 0; i < Size; i++)
219 {
220 *UnicodeString = CustomCP->MultiByteTable[(unsigned int)*CustomString];
221 UnicodeString++;
222 CustomString++;
223 }
224 }
225 else
226 {
227 /* multi-byte code page */
228 /* FIXME */
229 }
230
231 return(STATUS_SUCCESS);
232 }
233
234
235 WCHAR
236 RtlDowncaseUnicodeChar (IN WCHAR Source)
237 {
238 USHORT Offset;
239
240 if (Source < L'A')
241 return Source;
242
243 if (Source <= L'Z')
244 return Source + (L'a' - L'A');
245
246 if (Source < 0x80)
247 return Source;
248
249 Offset = ((USHORT)Source >> 8);
250 Offset = NlsUnicodeLowercaseTable[Offset];
251
252 Offset += (((USHORT)Source & 0x00F0) >> 4);
253 Offset = NlsUnicodeLowercaseTable[Offset];
254
255 Offset += ((USHORT)Source & 0x000F);
256 Offset = NlsUnicodeLowercaseTable[Offset];
257
258 return Source + (SHORT)Offset;
259 }
260
261
262 VOID STDCALL
263 RtlGetDefaultCodePage(PUSHORT AnsiCodePage,
264 PUSHORT OemCodePage)
265 {
266 *AnsiCodePage = NlsAnsiCodePage;
267 *OemCodePage = NlsOemCodePage;
268 }
269
270
271 VOID STDCALL
272 RtlInitCodePageTable(IN PUSHORT TableBase,
273 OUT PCPTABLEINFO CodePageTable)
274 {
275 PNLS_FILE_HEADER NlsFileHeader;
276 PUSHORT Ptr;
277 USHORT Offset;
278
279 DPRINT("RtlInitCodePageTable() called\n");
280
281 NlsFileHeader = (PNLS_FILE_HEADER)TableBase;
282
283 CodePageTable->CodePage = NlsFileHeader->CodePage;
284 CodePageTable->MaximumCharacterSize = NlsFileHeader->MaximumCharacterSize;
285 CodePageTable->DefaultChar = NlsFileHeader->DefaultChar;
286 CodePageTable->UniDefaultChar = NlsFileHeader->UniDefaultChar;
287 CodePageTable->TransDefaultChar = NlsFileHeader->TransDefaultChar;
288 CodePageTable->TransUniDefaultChar = NlsFileHeader->TransUniDefaultChar;
289
290 RtlCopyMemory(&CodePageTable->LeadByte,
291 &NlsFileHeader->LeadByte,
292 MAXIMUM_LEADBYTES);
293
294 /* Set Pointer to start of multi byte table */
295 Ptr = (PUSHORT)((ULONG_PTR)TableBase + 2 * NlsFileHeader->HeaderSize);
296
297 /* Get offset to the wide char table */
298 Offset = (USHORT)(*Ptr++) + NlsFileHeader->HeaderSize + 1;
299
300 /* Set pointer to the multi byte table */
301 CodePageTable->MultiByteTable = Ptr;
302
303 /* Skip ANSI and OEM table */
304 Ptr += 256;
305 if (*Ptr++)
306 Ptr += 256;
307
308 /* Set pointer to DBCS ranges */
309 CodePageTable->DBCSRanges = (PUSHORT)Ptr;
310
311 if (*Ptr > 0)
312 {
313 CodePageTable->DBCSCodePage = 1;
314 CodePageTable->DBCSOffsets = (PUSHORT)++Ptr;
315 }
316 else
317 {
318 CodePageTable->DBCSCodePage = 0;
319 CodePageTable->DBCSOffsets = 0;
320 }
321
322 CodePageTable->WideCharTable = (PVOID)((ULONG_PTR)TableBase + 2 * Offset);
323 }
324
325
326 VOID STDCALL
327 RtlInitNlsTables(IN PUSHORT AnsiTableBase,
328 IN PUSHORT OemTableBase,
329 IN PUSHORT CaseTableBase,
330 OUT PNLSTABLEINFO NlsTable)
331 {
332 DPRINT("RtlInitNlsTables()called\n");
333
334 RtlInitCodePageTable (AnsiTableBase,
335 &NlsTable->AnsiTableInfo);
336
337 RtlInitCodePageTable (OemTableBase,
338 &NlsTable->OemTableInfo);
339
340 NlsTable->UpperCaseTable = (PUSHORT)CaseTableBase + 2;
341 NlsTable->LowerCaseTable = (PUSHORT)CaseTableBase + *((PUSHORT)CaseTableBase + 1) + 2;
342 }
343
344
345 NTSTATUS STDCALL
346 RtlMultiByteToUnicodeN(PWCHAR UnicodeString,
347 ULONG UnicodeSize,
348 PULONG ResultSize,
349 PCHAR MbString,
350 ULONG MbSize)
351 {
352 ULONG Size = 0;
353 ULONG i;
354
355 if (NlsMbCodePageTag == FALSE)
356 {
357 /* single-byte code page */
358 if (MbSize > (UnicodeSize / sizeof(WCHAR)))
359 Size = UnicodeSize / sizeof(WCHAR);
360 else
361 Size = MbSize;
362
363 if (ResultSize != NULL)
364 *ResultSize = Size * sizeof(WCHAR);
365
366 for (i = 0; i < Size; i++)
367 {
368 *UnicodeString = NlsAnsiToUnicodeTable[(unsigned int)*MbString];
369 UnicodeString++;
370 MbString++;
371 }
372 }
373 else
374 {
375 /* multi-byte code page */
376 /* FIXME */
377 }
378
379 return(STATUS_SUCCESS);
380 }
381
382
383 NTSTATUS STDCALL
384 RtlMultiByteToUnicodeSize(PULONG UnicodeSize,
385 PCHAR MbString,
386 ULONG MbSize)
387 {
388 if (NlsMbCodePageTag == FALSE)
389 {
390 /* single-byte code page */
391 *UnicodeSize = MbSize * sizeof (WCHAR);
392 }
393 else
394 {
395 /* multi-byte code page */
396 /* FIXME */
397 }
398
399 return(STATUS_SUCCESS);
400 }
401
402
403 NTSTATUS STDCALL
404 RtlOemToUnicodeN(PWCHAR UnicodeString,
405 ULONG UnicodeSize,
406 PULONG ResultSize,
407 PCHAR OemString,
408 ULONG OemSize)
409 {
410 ULONG Size = 0;
411 ULONG i;
412
413 if (NlsMbOemCodePageTag == FALSE)
414 {
415 /* single-byte code page */
416 if (OemSize > (UnicodeSize / sizeof(WCHAR)))
417 Size = UnicodeSize / sizeof(WCHAR);
418 else
419 Size = OemSize;
420
421 if (ResultSize != NULL)
422 *ResultSize = Size * sizeof(WCHAR);
423
424 for (i = 0; i < Size; i++)
425 {
426 *UnicodeString = NlsOemToUnicodeTable[(unsigned int)*OemString];
427 UnicodeString++;
428 OemString++;
429 }
430 }
431 else
432 {
433 /* multi-byte code page */
434 /* FIXME */
435 }
436
437 return(STATUS_SUCCESS);
438 }
439
440
441 VOID STDCALL
442 RtlResetRtlTranslations(IN PNLSTABLEINFO NlsTable)
443 {
444 DPRINT("RtlResetRtlTranslations() called\n");
445
446 /* Set ANSI data */
447 NlsAnsiToUnicodeTable = NlsTable->AnsiTableInfo.MultiByteTable;
448 NlsUnicodeToAnsiTable = NlsTable->AnsiTableInfo.WideCharTable;
449 NlsDbcsUnicodeToAnsiTable = (PWCHAR)NlsTable->AnsiTableInfo.WideCharTable;
450 NlsMbCodePageTag = (NlsTable->AnsiTableInfo.DBCSCodePage != 0);
451 NlsLeadByteInfo = NlsTable->AnsiTableInfo.DBCSOffsets;
452 NlsAnsiCodePage = NlsTable->AnsiTableInfo.CodePage;
453 DPRINT("Ansi codepage %hu\n", NlsAnsiCodePage);
454
455 /* Set OEM data */
456 NlsOemToUnicodeTable = NlsTable->OemTableInfo.MultiByteTable;
457 NlsUnicodeToOemTable = NlsTable->OemTableInfo.WideCharTable;
458 NlsDbcsUnicodeToOemTable = (PWCHAR)NlsTable->OemTableInfo.WideCharTable;
459 NlsMbOemCodePageTag = (NlsTable->OemTableInfo.DBCSCodePage != 0);
460 NlsOemLeadByteInfo = NlsTable->OemTableInfo.DBCSOffsets;
461 NlsOemCodePage = NlsTable->OemTableInfo.CodePage;
462 DPRINT("Oem codepage %hu\n", NlsOemCodePage);
463
464 /* Set Unicode case map data */
465 NlsUnicodeUpcaseTable = NlsTable->UpperCaseTable;
466 NlsUnicodeLowercaseTable = NlsTable->LowerCaseTable;
467 }
468
469
470 NTSTATUS STDCALL
471 RtlUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP,
472 PCHAR CustomString,
473 ULONG CustomSize,
474 PULONG ResultSize,
475 PWCHAR UnicodeString,
476 ULONG UnicodeSize)
477 {
478 ULONG Size = 0;
479 ULONG i;
480
481 if (CustomCP->DBCSCodePage == 0)
482 {
483 /* single-byte code page */
484 if (UnicodeSize > (CustomSize * sizeof(WCHAR)))
485 Size = CustomSize;
486 else
487 Size = UnicodeSize / sizeof(WCHAR);
488
489 if (ResultSize != NULL)
490 *ResultSize = Size;
491
492 for (i = 0; i < Size; i++)
493 {
494 *CustomString = ((PCHAR)CustomCP->WideCharTable)[(unsigned int)*UnicodeString];
495 CustomString++;
496 UnicodeString++;
497 }
498 }
499 else
500 {
501 /* multi-byte code page */
502 /* FIXME */
503 }
504
505 return(STATUS_SUCCESS);
506 }
507
508
509 NTSTATUS
510 STDCALL
511 RtlUnicodeToMultiByteN(PCHAR MbString,
512 ULONG MbSize,
513 PULONG ResultSize,
514 PWCHAR UnicodeString,
515 ULONG UnicodeSize)
516 {
517 ULONG Size = 0;
518 ULONG i;
519
520 if (NlsMbCodePageTag == FALSE)
521 {
522 /* single-byte code page */
523 if (UnicodeSize > (MbSize * sizeof(WCHAR)))
524 Size = MbSize;
525 else
526 Size = UnicodeSize / sizeof(WCHAR);
527
528 if (ResultSize != NULL)
529 *ResultSize = Size;
530
531 for (i = 0; i < Size; i++)
532 {
533 *MbString = NlsUnicodeToAnsiTable[(unsigned int)*UnicodeString];
534 MbString++;
535 UnicodeString++;
536 }
537 }
538 else
539 {
540 /* multi-byte code page */
541 /* FIXME */
542 }
543
544 return(STATUS_SUCCESS);
545 }
546
547
548 NTSTATUS STDCALL
549 RtlUnicodeToMultiByteSize(PULONG MbSize,
550 PWCHAR UnicodeString,
551 ULONG UnicodeSize)
552 {
553 ULONG UnicodeLength;
554 ULONG MbLength;
555
556 if (NlsMbCodePageTag == FALSE)
557 {
558 /* single-byte code page */
559 *MbSize = UnicodeSize / sizeof (WCHAR);
560 }
561 else
562 {
563 /* multi-byte code page */
564 UnicodeLength = UnicodeSize / sizeof(WCHAR);
565 MbLength = 0;
566 while (UnicodeLength > 0)
567 {
568 if (NlsLeadByteInfo[*UnicodeString] & 0xff00)
569 MbLength++;
570
571 MbLength++;
572 UnicodeLength--;
573 UnicodeString++;
574 }
575
576 *MbSize = MbLength;
577 }
578
579 return(STATUS_SUCCESS);
580 }
581
582
583 NTSTATUS STDCALL
584 RtlUnicodeToOemN(PCHAR OemString,
585 ULONG OemSize,
586 PULONG ResultSize,
587 PWCHAR UnicodeString,
588 ULONG UnicodeSize)
589 {
590 ULONG Size = 0;
591 ULONG i;
592
593 if (NlsMbOemCodePageTag == FALSE)
594 {
595 /* single-byte code page */
596 if (UnicodeSize > (OemSize * sizeof(WCHAR)))
597 Size = OemSize;
598 else
599 Size = UnicodeSize / sizeof(WCHAR);
600
601 if (ResultSize != NULL)
602 *ResultSize = Size;
603
604 for (i = 0; i < Size; i++)
605 {
606 *OemString = NlsUnicodeToOemTable[(unsigned int)*UnicodeString];
607 OemString++;
608 UnicodeString++;
609 }
610 }
611 else
612 {
613 /* multi-byte code page */
614 /* FIXME */
615 }
616
617 return(STATUS_SUCCESS);
618 }
619
620
621 WCHAR STDCALL
622 RtlUpcaseUnicodeChar(IN WCHAR Source)
623 {
624 USHORT Offset;
625
626 if (Source < L'a')
627 return Source;
628
629 if (Source <= L'z')
630 return (Source - (L'a' - L'A'));
631
632 Offset = ((USHORT)Source >> 8);
633 Offset = NlsUnicodeUpcaseTable[Offset];
634
635 Offset += (((USHORT)Source & 0x00F0) >> 4);
636 Offset = NlsUnicodeUpcaseTable[Offset];
637
638 Offset += ((USHORT)Source & 0x000F);
639 Offset = NlsUnicodeUpcaseTable[Offset];
640
641 return Source + (SHORT)Offset;
642 }
643
644
645 NTSTATUS STDCALL
646 RtlUpcaseUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP,
647 PCHAR CustomString,
648 ULONG CustomSize,
649 PULONG ResultSize,
650 PWCHAR UnicodeString,
651 ULONG UnicodeSize)
652 {
653 ULONG Size = 0;
654 ULONG i;
655 WCHAR wc;
656
657 if (CustomCP->DBCSCodePage == 0)
658 {
659 /* single-byte code page */
660 if (UnicodeSize > (CustomSize * sizeof(WCHAR)))
661 Size = CustomSize;
662 else
663 Size = UnicodeSize / sizeof(WCHAR);
664
665 if (ResultSize != NULL)
666 *ResultSize = Size;
667
668 for (i = 0; i < Size; i++)
669 {
670 wc = RtlUpcaseUnicodeChar(*UnicodeString);
671 *CustomString = ((PCHAR)CustomCP->WideCharTable)[(unsigned int)wc];
672 CustomString++;
673 UnicodeString++;
674 }
675 }
676 else
677 {
678 /* multi-byte code page */
679 /* FIXME */
680 }
681
682 return(STATUS_SUCCESS);
683 }
684
685
686 NTSTATUS STDCALL
687 RtlUpcaseUnicodeToMultiByteN(PCHAR MbString,
688 ULONG MbSize,
689 PULONG ResultSize,
690 PWCHAR UnicodeString,
691 ULONG UnicodeSize)
692 {
693 ULONG Size = 0;
694 ULONG i;
695 WCHAR wc;
696
697 if (NlsMbCodePageTag == FALSE)
698 {
699 /* single-byte code page */
700 if (UnicodeSize > (MbSize * sizeof(WCHAR)))
701 Size = MbSize;
702 else
703 Size = UnicodeSize / sizeof(WCHAR);
704
705 if (ResultSize != NULL)
706 *ResultSize = Size;
707
708 for (i = 0; i < Size; i++)
709 {
710 wc = RtlUpcaseUnicodeChar(*UnicodeString);
711 *MbString = NlsUnicodeToAnsiTable[(unsigned int)wc];
712 MbString++;
713 UnicodeString++;
714 }
715 }
716 else
717 {
718 /* multi-byte code page */
719 /* FIXME */
720 }
721
722 return(STATUS_SUCCESS);
723 }
724
725
726 NTSTATUS STDCALL
727 RtlUpcaseUnicodeToOemN(PCHAR OemString,
728 ULONG OemSize,
729 PULONG ResultSize,
730 PWCHAR UnicodeString,
731 ULONG UnicodeSize)
732 {
733 ULONG Size = 0;
734 ULONG i;
735 UCHAR wc;
736
737 if (NlsMbOemCodePageTag == FALSE)
738 {
739 /* single-byte code page */
740 if (UnicodeSize > (OemSize * sizeof(WCHAR)))
741 Size = OemSize;
742 else
743 Size = UnicodeSize / sizeof(WCHAR);
744
745 if (ResultSize != NULL)
746 *ResultSize = Size;
747
748 for (i = 0; i < Size; i++)
749 {
750 wc = RtlUpcaseUnicodeChar(*UnicodeString);
751 *OemString = NlsUnicodeToOemTable[(unsigned int)wc];
752 OemString++;
753 UnicodeString++;
754 }
755 }
756 else
757 {
758 /* multi-byte code page */
759 /* FIXME */
760 }
761
762 return(STATUS_SUCCESS);
763 }
764
765
766 CHAR STDCALL
767 RtlUpperChar (IN CHAR Source)
768 {
769 WCHAR Unicode;
770 CHAR Destination;
771
772 if (NlsMbCodePageTag == FALSE)
773 {
774 /* single-byte code page */
775
776 /* ansi->unicode */
777 Unicode = NlsAnsiToUnicodeTable[(unsigned int)Source];
778
779 /* upcase conversion */
780 Unicode = RtlUpcaseUnicodeChar (Unicode);
781
782 /* unicode -> ansi */
783 Destination = NlsUnicodeToAnsiTable[(unsigned int)Unicode];
784 }
785 else
786 {
787 /* multi-byte code page */
788 /* FIXME */
789 Destination = Source;
790 }
791
792 return Destination;
793 }
794
795 /* EOF */