fixed all my bugs passing PUNICODE_STRING objects as PWSTR. Fixed signature of RtlMul...
[reactos.git] / reactos / ntoskrnl / rtl / nls.c
1 /* $Id: nls.c,v 1.19 2003/07/29 16:44:48 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 const 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 UnicodeString[i] = NlsAnsiToUnicodeTable[(unsigned int)MbString[i]];
380 }
381 else
382 {
383 /* multi-byte code page */
384 /* FIXME */
385 }
386
387 return(STATUS_SUCCESS);
388 }
389
390
391 /*
392 * @unimplemented
393 */
394 NTSTATUS STDCALL
395 RtlMultiByteToUnicodeSize(PULONG UnicodeSize,
396 PCHAR MbString,
397 ULONG MbSize)
398 {
399 if (NlsMbCodePageTag == FALSE)
400 {
401 /* single-byte code page */
402 *UnicodeSize = MbSize * sizeof (WCHAR);
403 }
404 else
405 {
406 /* multi-byte code page */
407 /* FIXME */
408 }
409
410 return(STATUS_SUCCESS);
411 }
412
413
414 /*
415 * @unimplemented
416 */
417 NTSTATUS STDCALL
418 RtlOemToUnicodeN(PWCHAR UnicodeString,
419 ULONG UnicodeSize,
420 PULONG ResultSize,
421 PCHAR OemString,
422 ULONG OemSize)
423 {
424 ULONG Size = 0;
425 ULONG i;
426
427 if (NlsMbOemCodePageTag == FALSE)
428 {
429 /* single-byte code page */
430 if (OemSize > (UnicodeSize / sizeof(WCHAR)))
431 Size = UnicodeSize / sizeof(WCHAR);
432 else
433 Size = OemSize;
434
435 if (ResultSize != NULL)
436 *ResultSize = Size * sizeof(WCHAR);
437
438 for (i = 0; i < Size; i++)
439 {
440 *UnicodeString = NlsOemToUnicodeTable[(unsigned int)*OemString];
441 UnicodeString++;
442 OemString++;
443 }
444 }
445 else
446 {
447 /* multi-byte code page */
448 /* FIXME */
449 }
450
451 return(STATUS_SUCCESS);
452 }
453
454
455 VOID STDCALL
456 RtlResetRtlTranslations(IN PNLSTABLEINFO NlsTable)
457 {
458 DPRINT("RtlResetRtlTranslations() called\n");
459
460 /* Set ANSI data */
461 NlsAnsiToUnicodeTable = NlsTable->AnsiTableInfo.MultiByteTable;
462 NlsUnicodeToAnsiTable = NlsTable->AnsiTableInfo.WideCharTable;
463 NlsDbcsUnicodeToAnsiTable = (PWCHAR)NlsTable->AnsiTableInfo.WideCharTable;
464 NlsMbCodePageTag = (NlsTable->AnsiTableInfo.DBCSCodePage != 0);
465 NlsLeadByteInfo = NlsTable->AnsiTableInfo.DBCSOffsets;
466 NlsAnsiCodePage = NlsTable->AnsiTableInfo.CodePage;
467 DPRINT("Ansi codepage %hu\n", NlsAnsiCodePage);
468
469 /* Set OEM data */
470 NlsOemToUnicodeTable = NlsTable->OemTableInfo.MultiByteTable;
471 NlsUnicodeToOemTable = NlsTable->OemTableInfo.WideCharTable;
472 NlsDbcsUnicodeToOemTable = (PWCHAR)NlsTable->OemTableInfo.WideCharTable;
473 NlsMbOemCodePageTag = (NlsTable->OemTableInfo.DBCSCodePage != 0);
474 NlsOemLeadByteInfo = NlsTable->OemTableInfo.DBCSOffsets;
475 NlsOemCodePage = NlsTable->OemTableInfo.CodePage;
476 DPRINT("Oem codepage %hu\n", NlsOemCodePage);
477
478 /* Set Unicode case map data */
479 NlsUnicodeUpcaseTable = NlsTable->UpperCaseTable;
480 NlsUnicodeLowercaseTable = NlsTable->LowerCaseTable;
481 }
482
483
484 /*
485 * @unimplemented
486 */
487 NTSTATUS STDCALL
488 RtlUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP,
489 PCHAR CustomString,
490 ULONG CustomSize,
491 PULONG ResultSize,
492 PWCHAR UnicodeString,
493 ULONG UnicodeSize)
494 {
495 ULONG Size = 0;
496 ULONG i;
497
498 if (CustomCP->DBCSCodePage == 0)
499 {
500 /* single-byte code page */
501 if (UnicodeSize > (CustomSize * sizeof(WCHAR)))
502 Size = CustomSize;
503 else
504 Size = UnicodeSize / sizeof(WCHAR);
505
506 if (ResultSize != NULL)
507 *ResultSize = Size;
508
509 for (i = 0; i < Size; i++)
510 {
511 *CustomString = ((PCHAR)CustomCP->WideCharTable)[(unsigned int)*UnicodeString];
512 CustomString++;
513 UnicodeString++;
514 }
515 }
516 else
517 {
518 /* multi-byte code page */
519 /* FIXME */
520 }
521
522 return(STATUS_SUCCESS);
523 }
524
525
526 /*
527 * @unimplemented
528 */
529 NTSTATUS
530 STDCALL
531 RtlUnicodeToMultiByteN(PCHAR MbString,
532 ULONG MbSize,
533 PULONG ResultSize,
534 PWCHAR UnicodeString,
535 ULONG UnicodeSize)
536 {
537 ULONG Size = 0;
538 ULONG i;
539
540 if (NlsMbCodePageTag == FALSE)
541 {
542 /* single-byte code page */
543 if (UnicodeSize > (MbSize * sizeof(WCHAR)))
544 Size = MbSize;
545 else
546 Size = UnicodeSize / sizeof(WCHAR);
547
548 if (ResultSize != NULL)
549 *ResultSize = Size;
550
551 for (i = 0; i < Size; i++)
552 {
553 *MbString = NlsUnicodeToAnsiTable[(unsigned int)*UnicodeString];
554 MbString++;
555 UnicodeString++;
556 }
557 }
558 else
559 {
560 /* multi-byte code page */
561 /* FIXME */
562 }
563
564 return(STATUS_SUCCESS);
565 }
566
567
568 /*
569 * @implemented
570 */
571 NTSTATUS STDCALL
572 RtlUnicodeToMultiByteSize(PULONG MbSize,
573 PWCHAR UnicodeString,
574 ULONG UnicodeSize)
575 {
576 ULONG UnicodeLength;
577 ULONG MbLength;
578
579 if (NlsMbCodePageTag == FALSE)
580 {
581 /* single-byte code page */
582 *MbSize = UnicodeSize / sizeof (WCHAR);
583 }
584 else
585 {
586 /* multi-byte code page */
587 UnicodeLength = UnicodeSize / sizeof(WCHAR);
588 MbLength = 0;
589 while (UnicodeLength > 0)
590 {
591 if (NlsLeadByteInfo[*UnicodeString] & 0xff00)
592 MbLength++;
593
594 MbLength++;
595 UnicodeLength--;
596 UnicodeString++;
597 }
598
599 *MbSize = MbLength;
600 }
601
602 return(STATUS_SUCCESS);
603 }
604
605
606 /*
607 * @unimplemented
608 */
609 NTSTATUS STDCALL
610 RtlUnicodeToOemN(PCHAR OemString,
611 ULONG OemSize,
612 PULONG ResultSize,
613 PWCHAR UnicodeString,
614 ULONG UnicodeSize)
615 {
616 ULONG Size = 0;
617 ULONG i;
618
619 if (NlsMbOemCodePageTag == FALSE)
620 {
621 /* single-byte code page */
622 if (UnicodeSize > (OemSize * sizeof(WCHAR)))
623 Size = OemSize;
624 else
625 Size = UnicodeSize / sizeof(WCHAR);
626
627 if (ResultSize != NULL)
628 *ResultSize = Size;
629
630 for (i = 0; i < Size; i++)
631 {
632 *OemString = NlsUnicodeToOemTable[(unsigned int)*UnicodeString];
633 OemString++;
634 UnicodeString++;
635 }
636 }
637 else
638 {
639 /* multi-byte code page */
640 /* FIXME */
641 }
642
643 return(STATUS_SUCCESS);
644 }
645
646
647 /*
648 * @implemented
649 */
650 WCHAR STDCALL
651 RtlUpcaseUnicodeChar(IN WCHAR Source)
652 {
653 USHORT Offset;
654
655 if (Source < L'a')
656 return Source;
657
658 if (Source <= L'z')
659 return (Source - (L'a' - L'A'));
660
661 Offset = ((USHORT)Source >> 8);
662 Offset = NlsUnicodeUpcaseTable[Offset];
663
664 Offset += (((USHORT)Source & 0x00F0) >> 4);
665 Offset = NlsUnicodeUpcaseTable[Offset];
666
667 Offset += ((USHORT)Source & 0x000F);
668 Offset = NlsUnicodeUpcaseTable[Offset];
669
670 return Source + (SHORT)Offset;
671 }
672
673
674 /*
675 * @unimplemented
676 */
677 NTSTATUS STDCALL
678 RtlUpcaseUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP,
679 PCHAR CustomString,
680 ULONG CustomSize,
681 PULONG ResultSize,
682 PWCHAR UnicodeString,
683 ULONG UnicodeSize)
684 {
685 ULONG Size = 0;
686 ULONG i;
687 WCHAR wc;
688
689 if (CustomCP->DBCSCodePage == 0)
690 {
691 /* single-byte code page */
692 if (UnicodeSize > (CustomSize * sizeof(WCHAR)))
693 Size = CustomSize;
694 else
695 Size = UnicodeSize / sizeof(WCHAR);
696
697 if (ResultSize != NULL)
698 *ResultSize = Size;
699
700 for (i = 0; i < Size; i++)
701 {
702 wc = RtlUpcaseUnicodeChar(*UnicodeString);
703 *CustomString = ((PCHAR)CustomCP->WideCharTable)[(unsigned int)wc];
704 CustomString++;
705 UnicodeString++;
706 }
707 }
708 else
709 {
710 /* multi-byte code page */
711 /* FIXME */
712 }
713
714 return(STATUS_SUCCESS);
715 }
716
717
718 /*
719 * @unimplemented
720 */
721 NTSTATUS STDCALL
722 RtlUpcaseUnicodeToMultiByteN(PCHAR MbString,
723 ULONG MbSize,
724 PULONG ResultSize,
725 PWCHAR UnicodeString,
726 ULONG UnicodeSize)
727 {
728 ULONG Size = 0;
729 ULONG i;
730 WCHAR wc;
731
732 if (NlsMbCodePageTag == FALSE)
733 {
734 /* single-byte code page */
735 if (UnicodeSize > (MbSize * sizeof(WCHAR)))
736 Size = MbSize;
737 else
738 Size = UnicodeSize / sizeof(WCHAR);
739
740 if (ResultSize != NULL)
741 *ResultSize = Size;
742
743 for (i = 0; i < Size; i++)
744 {
745 wc = RtlUpcaseUnicodeChar(*UnicodeString);
746 *MbString = NlsUnicodeToAnsiTable[(unsigned int)wc];
747 MbString++;
748 UnicodeString++;
749 }
750 }
751 else
752 {
753 /* multi-byte code page */
754 /* FIXME */
755 }
756
757 return(STATUS_SUCCESS);
758 }
759
760
761 /*
762 * @unimplemented
763 */
764 NTSTATUS STDCALL
765 RtlUpcaseUnicodeToOemN(PCHAR OemString,
766 ULONG OemSize,
767 PULONG ResultSize,
768 PWCHAR UnicodeString,
769 ULONG UnicodeSize)
770 {
771 ULONG Size = 0;
772 ULONG i;
773 UCHAR wc;
774
775 if (NlsMbOemCodePageTag == FALSE)
776 {
777 /* single-byte code page */
778 if (UnicodeSize > (OemSize * sizeof(WCHAR)))
779 Size = OemSize;
780 else
781 Size = UnicodeSize / sizeof(WCHAR);
782
783 if (ResultSize != NULL)
784 *ResultSize = Size;
785
786 for (i = 0; i < Size; i++)
787 {
788 wc = RtlUpcaseUnicodeChar(*UnicodeString);
789 *OemString = NlsUnicodeToOemTable[(unsigned int)wc];
790 OemString++;
791 UnicodeString++;
792 }
793 }
794 else
795 {
796 /* multi-byte code page */
797 /* FIXME */
798 }
799
800 return(STATUS_SUCCESS);
801 }
802
803
804 /*
805 * @unimplemented
806 */
807 CHAR STDCALL
808 RtlUpperChar (IN CHAR Source)
809 {
810 WCHAR Unicode;
811 CHAR Destination;
812
813 if (NlsMbCodePageTag == FALSE)
814 {
815 /* single-byte code page */
816
817 /* ansi->unicode */
818 Unicode = NlsAnsiToUnicodeTable[(unsigned int)Source];
819
820 /* upcase conversion */
821 Unicode = RtlUpcaseUnicodeChar (Unicode);
822
823 /* unicode -> ansi */
824 Destination = NlsUnicodeToAnsiTable[(unsigned int)Unicode];
825 }
826 else
827 {
828 /* multi-byte code page */
829 /* FIXME */
830 Destination = Source;
831 }
832
833 return Destination;
834 }
835
836 /* EOF */