finished applying @implemented and @unimplemented comments and remove the comments...
[reactos.git] / reactos / ntoskrnl / rtl / nls.c
1 /* $Id: nls.c,v 1.17 2003/07/11 01:23:15 royce 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 /*
197 * @unimplemented
198 */
199 NTSTATUS STDCALL
200 RtlCustomCPToUnicodeN(IN PCPTABLEINFO CustomCP,
201 PWCHAR UnicodeString,
202 ULONG UnicodeSize,
203 PULONG ResultSize,
204 PCHAR CustomString,
205 ULONG CustomSize)
206 {
207 ULONG Size = 0;
208 ULONG i;
209
210 if (CustomCP->DBCSCodePage == 0)
211 {
212 /* single-byte code page */
213 if (CustomSize > (UnicodeSize / sizeof(WCHAR)))
214 Size = UnicodeSize / sizeof(WCHAR);
215 else
216 Size = CustomSize;
217
218 if (ResultSize != NULL)
219 *ResultSize = Size * sizeof(WCHAR);
220
221 for (i = 0; i < Size; i++)
222 {
223 *UnicodeString = CustomCP->MultiByteTable[(unsigned int)*CustomString];
224 UnicodeString++;
225 CustomString++;
226 }
227 }
228 else
229 {
230 /* multi-byte code page */
231 /* FIXME */
232 }
233
234 return(STATUS_SUCCESS);
235 }
236
237
238 WCHAR
239 RtlDowncaseUnicodeChar (IN WCHAR Source)
240 {
241 USHORT Offset;
242
243 if (Source < L'A')
244 return Source;
245
246 if (Source <= L'Z')
247 return Source + (L'a' - L'A');
248
249 if (Source < 0x80)
250 return Source;
251
252 Offset = ((USHORT)Source >> 8);
253 Offset = NlsUnicodeLowercaseTable[Offset];
254
255 Offset += (((USHORT)Source & 0x00F0) >> 4);
256 Offset = NlsUnicodeLowercaseTable[Offset];
257
258 Offset += ((USHORT)Source & 0x000F);
259 Offset = NlsUnicodeLowercaseTable[Offset];
260
261 return Source + (SHORT)Offset;
262 }
263
264
265 /*
266 * @implemented
267 */
268 VOID STDCALL
269 RtlGetDefaultCodePage(PUSHORT AnsiCodePage,
270 PUSHORT OemCodePage)
271 {
272 *AnsiCodePage = NlsAnsiCodePage;
273 *OemCodePage = NlsOemCodePage;
274 }
275
276
277 /*
278 * @implemented
279 */
280 VOID STDCALL
281 RtlInitCodePageTable(IN PUSHORT TableBase,
282 OUT PCPTABLEINFO CodePageTable)
283 {
284 PNLS_FILE_HEADER NlsFileHeader;
285 PUSHORT Ptr;
286 USHORT Offset;
287
288 DPRINT("RtlInitCodePageTable() called\n");
289
290 NlsFileHeader = (PNLS_FILE_HEADER)TableBase;
291
292 CodePageTable->CodePage = NlsFileHeader->CodePage;
293 CodePageTable->MaximumCharacterSize = NlsFileHeader->MaximumCharacterSize;
294 CodePageTable->DefaultChar = NlsFileHeader->DefaultChar;
295 CodePageTable->UniDefaultChar = NlsFileHeader->UniDefaultChar;
296 CodePageTable->TransDefaultChar = NlsFileHeader->TransDefaultChar;
297 CodePageTable->TransUniDefaultChar = NlsFileHeader->TransUniDefaultChar;
298
299 RtlCopyMemory(&CodePageTable->LeadByte,
300 &NlsFileHeader->LeadByte,
301 MAXIMUM_LEADBYTES);
302
303 /* Set Pointer to start of multi byte table */
304 Ptr = (PUSHORT)((ULONG_PTR)TableBase + 2 * NlsFileHeader->HeaderSize);
305
306 /* Get offset to the wide char table */
307 Offset = (USHORT)(*Ptr++) + NlsFileHeader->HeaderSize + 1;
308
309 /* Set pointer to the multi byte table */
310 CodePageTable->MultiByteTable = Ptr;
311
312 /* Skip ANSI and OEM table */
313 Ptr += 256;
314 if (*Ptr++)
315 Ptr += 256;
316
317 /* Set pointer to DBCS ranges */
318 CodePageTable->DBCSRanges = (PUSHORT)Ptr;
319
320 if (*Ptr > 0)
321 {
322 CodePageTable->DBCSCodePage = 1;
323 CodePageTable->DBCSOffsets = (PUSHORT)++Ptr;
324 }
325 else
326 {
327 CodePageTable->DBCSCodePage = 0;
328 CodePageTable->DBCSOffsets = 0;
329 }
330
331 CodePageTable->WideCharTable = (PVOID)((ULONG_PTR)TableBase + 2 * Offset);
332 }
333
334
335 VOID STDCALL
336 RtlInitNlsTables(IN PUSHORT AnsiTableBase,
337 IN PUSHORT OemTableBase,
338 IN PUSHORT CaseTableBase,
339 OUT PNLSTABLEINFO NlsTable)
340 {
341 DPRINT("RtlInitNlsTables()called\n");
342
343 RtlInitCodePageTable (AnsiTableBase,
344 &NlsTable->AnsiTableInfo);
345
346 RtlInitCodePageTable (OemTableBase,
347 &NlsTable->OemTableInfo);
348
349 NlsTable->UpperCaseTable = (PUSHORT)CaseTableBase + 2;
350 NlsTable->LowerCaseTable = (PUSHORT)CaseTableBase + *((PUSHORT)CaseTableBase + 1) + 2;
351 }
352
353
354 /*
355 * @unimplemented
356 */
357 NTSTATUS STDCALL
358 RtlMultiByteToUnicodeN(PWCHAR UnicodeString,
359 ULONG UnicodeSize,
360 PULONG ResultSize,
361 PCHAR MbString,
362 ULONG MbSize)
363 {
364 ULONG Size = 0;
365 ULONG i;
366
367 if (NlsMbCodePageTag == FALSE)
368 {
369 /* single-byte code page */
370 if (MbSize > (UnicodeSize / sizeof(WCHAR)))
371 Size = UnicodeSize / sizeof(WCHAR);
372 else
373 Size = MbSize;
374
375 if (ResultSize != NULL)
376 *ResultSize = Size * sizeof(WCHAR);
377
378 for (i = 0; i < Size; i++)
379 {
380 *UnicodeString = NlsAnsiToUnicodeTable[(unsigned int)*MbString];
381 UnicodeString++;
382 MbString++;
383 }
384 }
385 else
386 {
387 /* multi-byte code page */
388 /* FIXME */
389 }
390
391 return(STATUS_SUCCESS);
392 }
393
394
395 /*
396 * @unimplemented
397 */
398 NTSTATUS STDCALL
399 RtlMultiByteToUnicodeSize(PULONG UnicodeSize,
400 PCHAR MbString,
401 ULONG MbSize)
402 {
403 if (NlsMbCodePageTag == FALSE)
404 {
405 /* single-byte code page */
406 *UnicodeSize = MbSize * sizeof (WCHAR);
407 }
408 else
409 {
410 /* multi-byte code page */
411 /* FIXME */
412 }
413
414 return(STATUS_SUCCESS);
415 }
416
417
418 /*
419 * @unimplemented
420 */
421 NTSTATUS STDCALL
422 RtlOemToUnicodeN(PWCHAR UnicodeString,
423 ULONG UnicodeSize,
424 PULONG ResultSize,
425 PCHAR OemString,
426 ULONG OemSize)
427 {
428 ULONG Size = 0;
429 ULONG i;
430
431 if (NlsMbOemCodePageTag == FALSE)
432 {
433 /* single-byte code page */
434 if (OemSize > (UnicodeSize / sizeof(WCHAR)))
435 Size = UnicodeSize / sizeof(WCHAR);
436 else
437 Size = OemSize;
438
439 if (ResultSize != NULL)
440 *ResultSize = Size * sizeof(WCHAR);
441
442 for (i = 0; i < Size; i++)
443 {
444 *UnicodeString = NlsOemToUnicodeTable[(unsigned int)*OemString];
445 UnicodeString++;
446 OemString++;
447 }
448 }
449 else
450 {
451 /* multi-byte code page */
452 /* FIXME */
453 }
454
455 return(STATUS_SUCCESS);
456 }
457
458
459 VOID STDCALL
460 RtlResetRtlTranslations(IN PNLSTABLEINFO NlsTable)
461 {
462 DPRINT("RtlResetRtlTranslations() called\n");
463
464 /* Set ANSI data */
465 NlsAnsiToUnicodeTable = NlsTable->AnsiTableInfo.MultiByteTable;
466 NlsUnicodeToAnsiTable = NlsTable->AnsiTableInfo.WideCharTable;
467 NlsDbcsUnicodeToAnsiTable = (PWCHAR)NlsTable->AnsiTableInfo.WideCharTable;
468 NlsMbCodePageTag = (NlsTable->AnsiTableInfo.DBCSCodePage != 0);
469 NlsLeadByteInfo = NlsTable->AnsiTableInfo.DBCSOffsets;
470 NlsAnsiCodePage = NlsTable->AnsiTableInfo.CodePage;
471 DPRINT("Ansi codepage %hu\n", NlsAnsiCodePage);
472
473 /* Set OEM data */
474 NlsOemToUnicodeTable = NlsTable->OemTableInfo.MultiByteTable;
475 NlsUnicodeToOemTable = NlsTable->OemTableInfo.WideCharTable;
476 NlsDbcsUnicodeToOemTable = (PWCHAR)NlsTable->OemTableInfo.WideCharTable;
477 NlsMbOemCodePageTag = (NlsTable->OemTableInfo.DBCSCodePage != 0);
478 NlsOemLeadByteInfo = NlsTable->OemTableInfo.DBCSOffsets;
479 NlsOemCodePage = NlsTable->OemTableInfo.CodePage;
480 DPRINT("Oem codepage %hu\n", NlsOemCodePage);
481
482 /* Set Unicode case map data */
483 NlsUnicodeUpcaseTable = NlsTable->UpperCaseTable;
484 NlsUnicodeLowercaseTable = NlsTable->LowerCaseTable;
485 }
486
487
488 /*
489 * @unimplemented
490 */
491 NTSTATUS STDCALL
492 RtlUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP,
493 PCHAR CustomString,
494 ULONG CustomSize,
495 PULONG ResultSize,
496 PWCHAR UnicodeString,
497 ULONG UnicodeSize)
498 {
499 ULONG Size = 0;
500 ULONG i;
501
502 if (CustomCP->DBCSCodePage == 0)
503 {
504 /* single-byte code page */
505 if (UnicodeSize > (CustomSize * sizeof(WCHAR)))
506 Size = CustomSize;
507 else
508 Size = UnicodeSize / sizeof(WCHAR);
509
510 if (ResultSize != NULL)
511 *ResultSize = Size;
512
513 for (i = 0; i < Size; i++)
514 {
515 *CustomString = ((PCHAR)CustomCP->WideCharTable)[(unsigned int)*UnicodeString];
516 CustomString++;
517 UnicodeString++;
518 }
519 }
520 else
521 {
522 /* multi-byte code page */
523 /* FIXME */
524 }
525
526 return(STATUS_SUCCESS);
527 }
528
529
530 /*
531 * @unimplemented
532 */
533 NTSTATUS
534 STDCALL
535 RtlUnicodeToMultiByteN(PCHAR MbString,
536 ULONG MbSize,
537 PULONG ResultSize,
538 PWCHAR UnicodeString,
539 ULONG UnicodeSize)
540 {
541 ULONG Size = 0;
542 ULONG i;
543
544 if (NlsMbCodePageTag == FALSE)
545 {
546 /* single-byte code page */
547 if (UnicodeSize > (MbSize * sizeof(WCHAR)))
548 Size = MbSize;
549 else
550 Size = UnicodeSize / sizeof(WCHAR);
551
552 if (ResultSize != NULL)
553 *ResultSize = Size;
554
555 for (i = 0; i < Size; i++)
556 {
557 *MbString = NlsUnicodeToAnsiTable[(unsigned int)*UnicodeString];
558 MbString++;
559 UnicodeString++;
560 }
561 }
562 else
563 {
564 /* multi-byte code page */
565 /* FIXME */
566 }
567
568 return(STATUS_SUCCESS);
569 }
570
571
572 /*
573 * @implemented
574 */
575 NTSTATUS STDCALL
576 RtlUnicodeToMultiByteSize(PULONG MbSize,
577 PWCHAR UnicodeString,
578 ULONG UnicodeSize)
579 {
580 ULONG UnicodeLength;
581 ULONG MbLength;
582
583 if (NlsMbCodePageTag == FALSE)
584 {
585 /* single-byte code page */
586 *MbSize = UnicodeSize / sizeof (WCHAR);
587 }
588 else
589 {
590 /* multi-byte code page */
591 UnicodeLength = UnicodeSize / sizeof(WCHAR);
592 MbLength = 0;
593 while (UnicodeLength > 0)
594 {
595 if (NlsLeadByteInfo[*UnicodeString] & 0xff00)
596 MbLength++;
597
598 MbLength++;
599 UnicodeLength--;
600 UnicodeString++;
601 }
602
603 *MbSize = MbLength;
604 }
605
606 return(STATUS_SUCCESS);
607 }
608
609
610 /*
611 * @unimplemented
612 */
613 NTSTATUS STDCALL
614 RtlUnicodeToOemN(PCHAR OemString,
615 ULONG OemSize,
616 PULONG ResultSize,
617 PWCHAR UnicodeString,
618 ULONG UnicodeSize)
619 {
620 ULONG Size = 0;
621 ULONG i;
622
623 if (NlsMbOemCodePageTag == FALSE)
624 {
625 /* single-byte code page */
626 if (UnicodeSize > (OemSize * sizeof(WCHAR)))
627 Size = OemSize;
628 else
629 Size = UnicodeSize / sizeof(WCHAR);
630
631 if (ResultSize != NULL)
632 *ResultSize = Size;
633
634 for (i = 0; i < Size; i++)
635 {
636 *OemString = NlsUnicodeToOemTable[(unsigned int)*UnicodeString];
637 OemString++;
638 UnicodeString++;
639 }
640 }
641 else
642 {
643 /* multi-byte code page */
644 /* FIXME */
645 }
646
647 return(STATUS_SUCCESS);
648 }
649
650
651 /*
652 * @implemented
653 */
654 WCHAR STDCALL
655 RtlUpcaseUnicodeChar(IN WCHAR Source)
656 {
657 USHORT Offset;
658
659 if (Source < L'a')
660 return Source;
661
662 if (Source <= L'z')
663 return (Source - (L'a' - L'A'));
664
665 Offset = ((USHORT)Source >> 8);
666 Offset = NlsUnicodeUpcaseTable[Offset];
667
668 Offset += (((USHORT)Source & 0x00F0) >> 4);
669 Offset = NlsUnicodeUpcaseTable[Offset];
670
671 Offset += ((USHORT)Source & 0x000F);
672 Offset = NlsUnicodeUpcaseTable[Offset];
673
674 return Source + (SHORT)Offset;
675 }
676
677
678 /*
679 * @unimplemented
680 */
681 NTSTATUS STDCALL
682 RtlUpcaseUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP,
683 PCHAR CustomString,
684 ULONG CustomSize,
685 PULONG ResultSize,
686 PWCHAR UnicodeString,
687 ULONG UnicodeSize)
688 {
689 ULONG Size = 0;
690 ULONG i;
691 WCHAR wc;
692
693 if (CustomCP->DBCSCodePage == 0)
694 {
695 /* single-byte code page */
696 if (UnicodeSize > (CustomSize * sizeof(WCHAR)))
697 Size = CustomSize;
698 else
699 Size = UnicodeSize / sizeof(WCHAR);
700
701 if (ResultSize != NULL)
702 *ResultSize = Size;
703
704 for (i = 0; i < Size; i++)
705 {
706 wc = RtlUpcaseUnicodeChar(*UnicodeString);
707 *CustomString = ((PCHAR)CustomCP->WideCharTable)[(unsigned int)wc];
708 CustomString++;
709 UnicodeString++;
710 }
711 }
712 else
713 {
714 /* multi-byte code page */
715 /* FIXME */
716 }
717
718 return(STATUS_SUCCESS);
719 }
720
721
722 /*
723 * @unimplemented
724 */
725 NTSTATUS STDCALL
726 RtlUpcaseUnicodeToMultiByteN(PCHAR MbString,
727 ULONG MbSize,
728 PULONG ResultSize,
729 PWCHAR UnicodeString,
730 ULONG UnicodeSize)
731 {
732 ULONG Size = 0;
733 ULONG i;
734 WCHAR wc;
735
736 if (NlsMbCodePageTag == FALSE)
737 {
738 /* single-byte code page */
739 if (UnicodeSize > (MbSize * sizeof(WCHAR)))
740 Size = MbSize;
741 else
742 Size = UnicodeSize / sizeof(WCHAR);
743
744 if (ResultSize != NULL)
745 *ResultSize = Size;
746
747 for (i = 0; i < Size; i++)
748 {
749 wc = RtlUpcaseUnicodeChar(*UnicodeString);
750 *MbString = NlsUnicodeToAnsiTable[(unsigned int)wc];
751 MbString++;
752 UnicodeString++;
753 }
754 }
755 else
756 {
757 /* multi-byte code page */
758 /* FIXME */
759 }
760
761 return(STATUS_SUCCESS);
762 }
763
764
765 /*
766 * @unimplemented
767 */
768 NTSTATUS STDCALL
769 RtlUpcaseUnicodeToOemN(PCHAR OemString,
770 ULONG OemSize,
771 PULONG ResultSize,
772 PWCHAR UnicodeString,
773 ULONG UnicodeSize)
774 {
775 ULONG Size = 0;
776 ULONG i;
777 UCHAR wc;
778
779 if (NlsMbOemCodePageTag == FALSE)
780 {
781 /* single-byte code page */
782 if (UnicodeSize > (OemSize * sizeof(WCHAR)))
783 Size = OemSize;
784 else
785 Size = UnicodeSize / sizeof(WCHAR);
786
787 if (ResultSize != NULL)
788 *ResultSize = Size;
789
790 for (i = 0; i < Size; i++)
791 {
792 wc = RtlUpcaseUnicodeChar(*UnicodeString);
793 *OemString = NlsUnicodeToOemTable[(unsigned int)wc];
794 OemString++;
795 UnicodeString++;
796 }
797 }
798 else
799 {
800 /* multi-byte code page */
801 /* FIXME */
802 }
803
804 return(STATUS_SUCCESS);
805 }
806
807
808 /*
809 * @unimplemented
810 */
811 CHAR STDCALL
812 RtlUpperChar (IN CHAR Source)
813 {
814 WCHAR Unicode;
815 CHAR Destination;
816
817 if (NlsMbCodePageTag == FALSE)
818 {
819 /* single-byte code page */
820
821 /* ansi->unicode */
822 Unicode = NlsAnsiToUnicodeTable[(unsigned int)Source];
823
824 /* upcase conversion */
825 Unicode = RtlUpcaseUnicodeChar (Unicode);
826
827 /* unicode -> ansi */
828 Destination = NlsUnicodeToAnsiTable[(unsigned int)Unicode];
829 }
830 else
831 {
832 /* multi-byte code page */
833 /* FIXME */
834 Destination = Source;
835 }
836
837 return Destination;
838 }
839
840 /* EOF */