:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / ntdll / rtl / unicode.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS kernel
5  * FILE:            lib/ntdll/rtl/unicode.c
6  * PURPOSE:         String functions
7  * PROGRAMMER:      Jason Filby (jasonfilby@yahoo.com)
8  * UPDATE HISTORY:
9  *                  Created 10/08/98
10  */
11
12 #include <ddk/ntddk.h>
13 #include <ntdll/rtl.h>
14 //#include <internal/nls.h>
15 #include <ctype.h>
16 #include <ntos/minmax.h>
17 #define NDEBUG
18 #include <ntdll/ntdll.h>
19
20 /* FUNCTIONS *****************************************************************/
21
22 WCHAR
23 STDCALL
24 RtlAnsiCharToUnicodeChar (
25         IN      CHAR    AnsiChar
26         )
27 {
28         ULONG Size;
29         WCHAR UnicodeChar;
30
31         Size = 1;
32 #if 0
33         Size = (NlsLeadByteInfo[AnsiChar] == 0) ? 1 : 2;
34 #endif
35
36         RtlMultiByteToUnicodeN (&UnicodeChar,
37                                 sizeof(WCHAR),
38                                 NULL,
39                                 &AnsiChar,
40                                 Size);
41
42         return UnicodeChar;
43 }
44
45
46 ULONG
47 STDCALL
48 RtlAnsiStringToUnicodeSize (
49         IN      PANSI_STRING    AnsiString
50         )
51 {
52         ULONG Size;
53
54         RtlMultiByteToUnicodeSize (&Size,
55                                    AnsiString->Buffer,
56                                    AnsiString->Length);
57
58         return Size;
59 }
60
61
62 NTSTATUS
63 STDCALL
64 RtlAnsiStringToUnicodeString(
65         IN OUT  PUNICODE_STRING DestinationString,
66         IN      PANSI_STRING    SourceString,
67         IN      BOOLEAN         AllocateDestinationString
68         )
69 {
70         NTSTATUS Status;
71         ULONG Length;
72
73         if (NlsMbCodePageTag == TRUE)
74                 Length = RtlAnsiStringToUnicodeSize (SourceString);
75         else
76                 Length = SourceString->Length * sizeof(WCHAR);
77
78         if (Length > 65535)
79                 return STATUS_INVALID_PARAMETER_2;
80
81         if (AllocateDestinationString == TRUE)
82         {
83                 DestinationString->MaximumLength = Length + sizeof(WCHAR);
84                 DestinationString->Buffer =
85                         RtlAllocateHeap (RtlGetProcessHeap (),
86                                          0,
87                                          DestinationString->MaximumLength);
88                 if (DestinationString->Buffer == NULL)
89                         return STATUS_NO_MEMORY;
90         }
91         else
92         {
93                 if (Length + sizeof(WCHAR) > DestinationString->MaximumLength)
94                 {
95                         DPRINT("STATUS_BUFFER_TOO_SMALL\n");
96                         return STATUS_BUFFER_TOO_SMALL;
97                 }
98         }
99         DestinationString->Length = Length;
100
101         RtlZeroMemory (DestinationString->Buffer,
102                        DestinationString->Length);
103
104         Status = RtlMultiByteToUnicodeN (DestinationString->Buffer,
105                                          DestinationString->Length,
106                                          NULL,
107                                          SourceString->Buffer,
108                                          SourceString->Length);
109         if (!NT_SUCCESS(Status))
110         {
111                 if (AllocateDestinationString)
112                 {
113                         RtlFreeHeap (RtlGetProcessHeap (),
114                                      0,
115                                      DestinationString->Buffer);
116                 }
117                 return Status;
118         }
119
120         DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
121
122         return STATUS_SUCCESS;
123 }
124
125
126 NTSTATUS
127 STDCALL
128 RtlAppendAsciizToString (
129         IN OUT  PSTRING Destination,
130         IN      PCSZ    Source
131         )
132 {
133         ULONG Length;
134         PCHAR Ptr;
135
136         if (Source == NULL)
137                 return STATUS_SUCCESS;
138
139         Length = strlen (Source);
140         if (Destination->Length + Length >= Destination->MaximumLength)
141                 return STATUS_BUFFER_TOO_SMALL;
142
143         Ptr = Destination->Buffer + Destination->Length;
144         memmove (Ptr,
145                  Source,
146                  Length);
147         Ptr += Length;
148         *Ptr = 0;
149
150         Destination->Length += Length;
151
152         return STATUS_SUCCESS;
153 }
154
155
156 NTSTATUS
157 STDCALL
158 RtlAppendStringToString (
159         IN OUT  PSTRING Destination,
160         IN      PSTRING Source
161         )
162 {
163         PCHAR Ptr;
164
165         if (Source->Length == 0)
166                 return STATUS_SUCCESS;
167
168         if (Destination->Length + Source->Length >= Destination->MaximumLength)
169                 return STATUS_BUFFER_TOO_SMALL;
170
171         Ptr = Destination->Buffer + Destination->Length;
172         memmove (Ptr,
173                  Source->Buffer,
174                  Source->Length);
175         Ptr += Source->Length;
176         *Ptr = 0;
177
178         Destination->Length += Source->Length;
179
180         return STATUS_SUCCESS;
181 }
182
183
184 NTSTATUS
185 STDCALL
186 RtlAppendUnicodeStringToString (
187         IN OUT  PUNICODE_STRING Destination,
188         IN      PUNICODE_STRING Source
189         )
190 {
191         PWCHAR Src;
192         PWCHAR Dest;
193         ULONG  i;
194
195         if ((Source->Length + Destination->Length) >= Destination->MaximumLength)
196                 return STATUS_BUFFER_TOO_SMALL;
197
198         Src  = Source->Buffer;
199         Dest = Destination->Buffer + (Destination->Length / sizeof (WCHAR));
200         for (i = 0; i < (Source->Length / sizeof(WCHAR)); i++)
201         {
202                 *Dest = *Src;
203                 Dest++;
204                 Src++;
205         }
206         *Dest = 0;
207
208         Destination->Length += Source->Length;
209
210         return STATUS_SUCCESS;
211 }
212
213
214 NTSTATUS STDCALL
215 RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination,
216                          IN PWSTR Source)
217 {
218   PWCHAR Src;
219   PWCHAR Dest;
220   ULONG i;
221   ULONG slen;
222
223   slen = wcslen(Source) * sizeof(WCHAR);
224
225   if (Destination->Length + slen >= Destination->MaximumLength)
226     return(STATUS_BUFFER_TOO_SMALL);
227
228   Src = Source;
229   Dest = Destination->Buffer + (Destination->Length / sizeof(WCHAR));
230
231   for (i = 0; i < (slen / sizeof(WCHAR)); i++)
232     {
233       *Dest = *Src;
234       Dest++;
235       Src++;
236     }
237   *Dest = 0;
238
239   Destination->Length += slen;
240
241   return(STATUS_SUCCESS);
242 }
243
244
245 NTSTATUS
246 STDCALL
247 RtlCharToInteger (
248         IN      PCSZ    String,
249         IN      ULONG   Base,
250         IN OUT  PULONG  Value)
251 {
252         ULONG Val;
253
254         *Value = 0;
255
256         if (Base == 0)
257         {
258                 Base = 10;
259                 if (*String == '0')
260                 {
261                         Base = 8;
262                         String++;
263                         if ((*String == 'x') && isxdigit (String[1]))
264                         {
265                                 String++;
266                                 Base = 16;
267                         }
268                 }
269         }
270
271         if (!isxdigit (*String))
272                 return STATUS_INVALID_PARAMETER;
273
274         while (isxdigit (*String) &&
275                (Val = isdigit (*String) ? * String - '0' : (islower (*String)
276                 ? toupper (*String) : *String) - 'A' + 10) < Base)
277         {
278                 *Value = *Value * Base + Val;
279                 String++;
280         }
281
282         return STATUS_SUCCESS;
283 }
284
285
286 LONG
287 STDCALL
288 RtlCompareString (
289         IN      PSTRING String1,
290         IN      PSTRING String2,
291         IN      BOOLEAN CaseInsensitive
292         )
293 {
294         ULONG len1, len2;
295         PCHAR s1, s2;
296         CHAR  c1, c2;
297
298         if (String1 && String2)
299         {
300                 len1 = String1->Length;
301                 len2 = String2->Length;
302                 s1 = String1->Buffer;
303                 s2 = String2->Buffer;
304
305                 if (s1 && s2)
306                 {
307                         if (CaseInsensitive)
308                         {
309                                 while (1)
310                                 {
311                                         c1 = len1-- ? RtlUpperChar (*s1++) : 0;
312                                         c2 = len2-- ? RtlUpperChar (*s2++) : 0;
313                                         if (!c1 || !c2 || c1 != c2)
314                                                 return c1 - c2;
315                                 }
316                         }
317                         else
318                         {
319                                 while (1)
320                                 {
321                                         c1 = len1-- ? *s1++ : 0;
322                                         c2 = len2-- ? *s2++ : 0;
323                                         if (!c1 || !c2 || c1 != c2)
324                                                 return c1 - c2;
325                                 }
326                         }
327                 }
328         }
329
330         return 0;
331 }
332
333
334 LONG
335 STDCALL
336 RtlCompareUnicodeString (
337         IN      PUNICODE_STRING String1,
338         IN      PUNICODE_STRING String2,
339         IN      BOOLEAN         CaseInsensitive
340         )
341 {
342         ULONG len1, len2;
343         PWCHAR s1, s2;
344         WCHAR  c1, c2;
345
346         if (String1 && String2)
347         {
348                 len1 = String1->Length / sizeof(WCHAR);
349                 len2 = String2->Length / sizeof(WCHAR);
350                 s1 = String1->Buffer;
351                 s2 = String2->Buffer;
352
353                 if (s1 && s2)
354                 {
355                         if (CaseInsensitive)
356                         {
357                                 while (1)
358                                 {
359                                         c1 = len1-- ? RtlUpcaseUnicodeChar (*s1++) : 0;
360                                         c2 = len2-- ? RtlUpcaseUnicodeChar (*s2++) : 0;
361                                         if (!c1 || !c2 || c1 != c2)
362                                                 return c1 - c2;
363                                 }
364                         }
365                         else
366                         {
367                                 while (1)
368                                 {
369                                         c1 = len1-- ? *s1++ : 0;
370                                         c2 = len2-- ? *s2++ : 0;
371                                         if (!c1 || !c2 || c1 != c2)
372                                                 return c1 - c2;
373                                 }
374                         }
375                 }
376         }
377
378         return 0;
379 }
380
381
382 VOID
383 STDCALL
384 RtlCopyString (
385         IN OUT  PSTRING DestinationString,
386         IN      PSTRING SourceString
387         )
388 {
389         ULONG copylen, i;
390         PCHAR Src, Dest;
391
392         if (SourceString == NULL)
393         {
394                 DestinationString->Length = 0;
395                 return;
396         }
397
398         copylen = min (DestinationString->MaximumLength - sizeof(CHAR),
399                        SourceString->Length);
400         Src = SourceString->Buffer;
401         Dest = DestinationString->Buffer;
402
403         for (i = 0; i < copylen; i++)
404         {
405                 *Dest = *Src;
406                 Dest++;
407                 Src++;
408         }
409         *Dest = 0;
410
411         DestinationString->Length = copylen;
412 }
413
414
415 VOID
416 STDCALL
417 RtlCopyUnicodeString (
418         IN OUT  PUNICODE_STRING DestinationString,
419         IN      PUNICODE_STRING SourceString
420         )
421 {
422         ULONG copylen, i;
423         PWCHAR Src, Dest;
424
425         if (SourceString == NULL)
426         {
427                 DestinationString->Length = 0;
428                 return;
429         }
430
431         copylen = min (DestinationString->MaximumLength - sizeof(WCHAR),
432                        SourceString->Length);
433         Src = SourceString->Buffer;
434         Dest = DestinationString->Buffer;
435
436         for (i = 0; i < (copylen / sizeof (WCHAR)); i++)
437         {
438                 *Dest = *Src;
439                 Dest++;
440                 Src++;
441         }
442         *Dest = 0;
443
444         DestinationString->Length = copylen;
445 }
446
447
448 BOOLEAN
449 STDCALL
450 RtlCreateUnicodeString (
451         IN OUT  PUNICODE_STRING Destination,
452         IN      PWSTR           Source
453         )
454 {
455         ULONG Length;
456
457         Length = (wcslen (Source) + 1) * sizeof(WCHAR);
458
459         Destination->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
460                                                0,
461                                                Length);
462         if (Destination->Buffer == NULL)
463                 return FALSE;
464
465         memmove (Destination->Buffer,
466                  Source,
467                  Length);
468
469         Destination->MaximumLength = Length;
470         Destination->Length = Length - sizeof (WCHAR);
471
472         return TRUE;
473 }
474
475
476 BOOLEAN STDCALL
477 RtlCreateUnicodeStringFromAsciiz (OUT   PUNICODE_STRING Destination,
478                                   IN    PCSZ            Source)
479 {
480         ANSI_STRING AnsiString;
481         NTSTATUS Status;
482
483         RtlInitAnsiString (&AnsiString,
484                            Source);
485
486         Status = RtlAnsiStringToUnicodeString (Destination,
487                                                &AnsiString,
488                                                TRUE);
489
490         return NT_SUCCESS(Status);
491 }
492
493
494 NTSTATUS
495 STDCALL
496 RtlDowncaseUnicodeString (
497         IN OUT  PUNICODE_STRING DestinationString,
498         IN      PUNICODE_STRING SourceString,
499         IN      BOOLEAN         AllocateDestinationString
500         )
501 {
502         ULONG i;
503         PWCHAR Src, Dest;
504
505         if (AllocateDestinationString == TRUE)
506         {
507                 DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR);
508                 DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
509                                                              0,
510                                                              SourceString->Length + sizeof(WCHAR));
511         }
512         else
513         {
514                 if (SourceString->Length >= DestinationString->MaximumLength)
515                         return STATUS_BUFFER_TOO_SMALL;
516         }
517         DestinationString->Length = SourceString->Length;
518
519         Src = SourceString->Buffer;
520         Dest = DestinationString->Buffer;
521         for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
522         {
523                 if (*Src < L'A')
524                 {
525                         *Dest = *Src;
526                 }
527                 else if (*Src <= L'Z')
528                 {
529                         *Dest = (*Src + (L'a' - L'A'));
530                 }
531                 else
532                 {
533                         /* FIXME: characters above 'Z' */
534                         *Dest = *Src;
535                 }
536
537                 Dest++;
538                 Src++;
539         }
540         *Dest = 0;
541
542         return STATUS_SUCCESS;
543 }
544
545
546 BOOLEAN
547 STDCALL
548 RtlEqualComputerName (
549         IN      PUNICODE_STRING ComputerName1,
550         IN      PUNICODE_STRING ComputerName2
551         )
552 {
553         return RtlEqualDomainName (ComputerName1,
554                                    ComputerName2);
555 }
556
557
558 BOOLEAN
559 STDCALL
560 RtlEqualDomainName (
561         IN      PUNICODE_STRING DomainName1,
562         IN      PUNICODE_STRING DomainName2
563         )
564 {
565         OEM_STRING OemString1;
566         OEM_STRING OemString2;
567         BOOLEAN Result;
568
569         RtlUpcaseUnicodeStringToOemString (&OemString1,
570                                            DomainName1,
571                                            TRUE);
572         RtlUpcaseUnicodeStringToOemString (&OemString2,
573                                            DomainName2,
574                                            TRUE);
575
576         Result = RtlEqualString (&OemString1,
577                                  &OemString2,
578                                  FALSE);
579
580         RtlFreeOemString (&OemString1);
581         RtlFreeOemString (&OemString2);
582
583         return Result;
584 }
585
586
587 BOOLEAN
588 STDCALL
589 RtlEqualString (
590         IN      PSTRING String1,
591         IN      PSTRING String2,
592         IN      BOOLEAN CaseInsensitive
593         )
594 {
595         ULONG i;
596         CHAR c1, c2;
597         PCHAR p1, p2;
598
599         if (String1->Length != String2->Length)
600                 return FALSE;
601
602         p1 = String1->Buffer;
603         p2 = String2->Buffer;
604         for (i = 0; i < String1->Length; i++)
605         {
606                 if (CaseInsensitive == TRUE)
607                 {
608                         c1 = RtlUpperChar (*p1);
609                         c2 = RtlUpperChar (*p2);
610                 }
611                 else
612                 {
613                         c1 = *p1;
614                         c2 = *p2;
615                 }
616
617                 if (c1 != c2)
618                         return FALSE;
619
620                 p1++;
621                 p2++;
622         }
623
624         return TRUE;
625 }
626
627
628 BOOLEAN
629 STDCALL
630 RtlEqualUnicodeString (
631         IN      PUNICODE_STRING String1,
632         IN      PUNICODE_STRING String2,
633         IN      BOOLEAN         CaseInsensitive
634         )
635 {
636         ULONG i;
637         WCHAR wc1, wc2;
638         PWCHAR pw1, pw2;
639
640         if (String1->Length != String2->Length)
641                 return FALSE;
642
643         pw1 = String1->Buffer;
644         pw2 = String2->Buffer;
645
646         for (i = 0; i < String1->Length / sizeof(WCHAR); i++)
647         {
648                 if (CaseInsensitive == TRUE)
649                 {
650                         wc1 = RtlUpcaseUnicodeChar (*pw1);
651                         wc2 = RtlUpcaseUnicodeChar (*pw2);
652                 }
653                 else
654                 {
655                         wc1 = *pw1;
656                         wc2 = *pw2;
657                 }
658
659                 if (wc1 != wc2)
660                         return FALSE;
661
662                 pw1++;
663                 pw2++;
664         }
665
666         return TRUE;
667 }
668
669
670 VOID
671 STDCALL
672 RtlEraseUnicodeString (
673         IN      PUNICODE_STRING String
674         )
675 {
676         if (String->Buffer == NULL)
677                 return;
678
679         if (String->MaximumLength == 0)
680                 return;
681
682         memset (String->Buffer,
683                 0,
684                 String->MaximumLength);
685
686         String->Length = 0;
687 }
688
689
690 VOID
691 STDCALL
692 RtlFreeAnsiString (
693         IN      PANSI_STRING    AnsiString
694         )
695 {
696         if (AnsiString->Buffer == NULL)
697                 return;
698
699         RtlFreeHeap (RtlGetProcessHeap (),
700                      0,
701                      AnsiString->Buffer);
702
703         AnsiString->Buffer = NULL;
704         AnsiString->Length = 0;
705         AnsiString->MaximumLength = 0;
706 }
707
708
709 VOID
710 STDCALL
711 RtlFreeOemString (
712         IN      POEM_STRING     OemString
713         )
714 {
715         if (OemString->Buffer == NULL)
716                 return;
717
718         RtlFreeHeap (RtlGetProcessHeap (),
719                      0,
720                      OemString->Buffer);
721
722         OemString->Buffer = NULL;
723         OemString->Length = 0;
724         OemString->MaximumLength = 0;
725 }
726
727
728 VOID
729 STDCALL
730 RtlFreeUnicodeString (
731         IN      PUNICODE_STRING UnicodeString
732         )
733 {
734         if (UnicodeString->Buffer == NULL)
735                 return;
736
737         RtlFreeHeap (RtlGetProcessHeap (),
738                      0,
739                      UnicodeString->Buffer);
740
741         UnicodeString->Buffer = NULL;
742         UnicodeString->Length = 0;
743         UnicodeString->MaximumLength = 0;
744 }
745
746
747 VOID
748 STDCALL
749 RtlInitAnsiString (
750         IN OUT  PANSI_STRING    DestinationString,
751         IN      PCSZ            SourceString
752         )
753 {
754         ULONG DestSize;
755
756         if(SourceString==NULL)
757         {
758                 DestinationString->Length = 0;
759                 DestinationString->MaximumLength = 0;
760         }
761         else
762         {
763                 DestSize = strlen ((const char *)SourceString);
764                 DestinationString->Length = DestSize;
765                 DestinationString->MaximumLength = DestSize + 1;
766         }
767         DestinationString->Buffer = (PCHAR)SourceString;
768 }
769
770
771 VOID
772 STDCALL
773 RtlInitString (
774         IN OUT  PSTRING DestinationString,
775         IN      PCSZ    SourceString
776         )
777 {
778         ULONG DestSize;
779
780         if (SourceString == NULL)
781         {
782                 DestinationString->Length = 0;
783                 DestinationString->MaximumLength = 0;
784         }
785         else
786         {
787                 DestSize = strlen((const char *)SourceString);
788                 DestinationString->Length = DestSize;
789                 DestinationString->MaximumLength = DestSize + sizeof(CHAR);
790         }
791         DestinationString->Buffer = (PCHAR)SourceString;
792 }
793
794
795 VOID
796 STDCALL
797 RtlInitUnicodeString (
798         IN OUT  PUNICODE_STRING DestinationString,
799         IN      PCWSTR          SourceString
800         )
801 {
802         ULONG DestSize;
803
804         if (SourceString==NULL)
805         {
806                 DestinationString->Length=0;
807                 DestinationString->MaximumLength=0;
808         }
809         else
810         {
811                 DestSize = wcslen((PWSTR)SourceString) * sizeof(WCHAR);
812                 DestinationString->Length = DestSize;
813                 DestinationString->MaximumLength = DestSize + sizeof(WCHAR);
814         }
815         DestinationString->Buffer = (PWSTR)SourceString;
816 }
817
818
819 NTSTATUS
820 STDCALL
821 RtlIntegerToChar (
822         IN      ULONG   Value,
823         IN      ULONG   Base,
824         IN      ULONG   Length,
825         IN OUT  PCHAR   String
826         )
827 {
828         ULONG Radix;
829         CHAR  temp[33];
830         ULONG v = Value;
831         ULONG i;
832         PCHAR tp;
833         PCHAR sp;
834
835         Radix = Base;
836         if (Radix == 0)
837                 Radix = 10;
838
839         if ((Radix != 2) && (Radix != 8) &&
840             (Radix != 10) && (Radix != 16))
841                 return STATUS_INVALID_PARAMETER;
842
843         tp = temp;
844         while (v || tp == temp)
845         {
846                 i = v % Radix;
847                 v = v / Radix;
848                 if (i < 10)
849                         *tp = i + '0';
850                 else
851                         *tp = i + 'a' - 10;
852                 tp++;
853         }
854
855         if (tp - temp >= Length)
856                 return STATUS_BUFFER_TOO_SMALL;
857
858         sp = String;
859         while (tp > temp)
860                 *sp++ = *--tp;
861         *sp = 0;
862
863         return STATUS_SUCCESS;
864 }
865
866
867 NTSTATUS
868 STDCALL
869 RtlIntegerToUnicodeString (
870         IN      ULONG           Value,
871         IN      ULONG           Base,   /* optional */
872         IN OUT  PUNICODE_STRING String
873         )
874 {
875         ANSI_STRING AnsiString;
876         CHAR Buffer[33];
877         NTSTATUS Status;
878
879         Status = RtlIntegerToChar (Value,
880                                    Base,
881                                    33,
882                                    Buffer);
883         if (!NT_SUCCESS(Status))
884                 return Status;
885
886         AnsiString.Buffer = Buffer;
887         AnsiString.Length = strlen (Buffer);
888         AnsiString.MaximumLength = 33;
889
890         Status = RtlAnsiStringToUnicodeString (String,
891                                                &AnsiString,
892                                                FALSE);
893
894         return Status;
895 }
896
897
898 NTSTATUS
899 STDCALL
900 RtlLargeIntegerToChar (
901         IN      PLARGE_INTEGER  Value,
902         IN      ULONG           Base,
903         IN      ULONG           Length,
904         IN OUT  PCHAR           String
905         )
906 {
907         ULONG Radix;
908         CHAR  temp[65];
909         ULONGLONG v = Value->QuadPart;
910         ULONG i;
911         PCHAR tp;
912         PCHAR sp;
913
914         Radix = Base;
915         if (Radix == 0)
916                 Radix = 10;
917
918         if ((Radix != 2) && (Radix != 8) &&
919             (Radix != 10) && (Radix != 16))
920                 return STATUS_INVALID_PARAMETER;
921
922         tp = temp;
923         while (v || tp == temp)
924         {
925                 i = v % Radix;
926                 v = v / Radix;
927                 if (i < 10)
928                         *tp = i + '0';
929                 else
930                         *tp = i + 'a' - 10;
931                 tp++;
932         }
933
934         if (tp - temp >= Length)
935                 return STATUS_BUFFER_TOO_SMALL;
936
937         sp = String;
938         while (tp > temp)
939                 *sp++ = *--tp;
940         *sp = 0;
941
942         return STATUS_SUCCESS;
943 }
944
945
946 ULONG
947 STDCALL
948 RtlOemStringToUnicodeSize (
949         IN      POEM_STRING     OemString
950         )
951 {
952         ULONG Size;
953
954         RtlMultiByteToUnicodeSize (&Size,
955                                    OemString->Buffer,
956                                    OemString->Length);
957
958         return Size;
959 }
960
961
962 NTSTATUS
963 STDCALL
964 RtlOemStringToUnicodeString (
965         IN OUT  PUNICODE_STRING DestinationString,
966         IN      POEM_STRING     SourceString,
967         IN      BOOLEAN         AllocateDestinationString
968         )
969 {
970         NTSTATUS Status;
971         ULONG Length;
972
973         if (NlsMbCodePageTag == TRUE)
974                 Length = RtlAnsiStringToUnicodeSize (SourceString);
975         else
976                 Length = SourceString->Length * sizeof(WCHAR);
977
978         if (Length > 65535)
979                 return STATUS_INVALID_PARAMETER_2;
980
981         if (AllocateDestinationString == TRUE)
982         {
983                 DestinationString->MaximumLength = Length + sizeof(WCHAR);
984                 DestinationString->Buffer =
985                         RtlAllocateHeap (RtlGetProcessHeap (),
986                                          0,
987                                          DestinationString->MaximumLength);
988                 if (DestinationString->Buffer == NULL)
989                         return STATUS_NO_MEMORY;
990         }
991         else
992         {
993                 if (Length + sizeof(WCHAR) > DestinationString->MaximumLength)
994                 {
995                         DPRINT("STATUS_BUFFER_TOO_SMALL\n");
996                         return STATUS_BUFFER_TOO_SMALL;
997                 }
998         }
999         DestinationString->Length = Length;
1000
1001         RtlZeroMemory (DestinationString->Buffer,
1002                        DestinationString->Length);
1003
1004         Status = RtlOemToUnicodeN (DestinationString->Buffer,
1005                                    DestinationString->Length,
1006                                    NULL,
1007                                    SourceString->Buffer,
1008                                    SourceString->Length);
1009         if (!NT_SUCCESS(Status))
1010         {
1011                 if (AllocateDestinationString)
1012                 {
1013                         RtlFreeHeap (RtlGetProcessHeap (),
1014                                      0,
1015                                      DestinationString->Buffer);
1016                 }
1017                 return Status;
1018         }
1019
1020         DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
1021
1022         return STATUS_SUCCESS;
1023 }
1024
1025
1026 BOOLEAN
1027 STDCALL
1028 RtlPrefixString (
1029         PANSI_STRING    String1,
1030         PANSI_STRING    String2,
1031         BOOLEAN         CaseInsensitive
1032         )
1033 {
1034         PCHAR pc1;
1035         PCHAR pc2;
1036         ULONG Length;
1037
1038         if (String2->Length < String1->Length)
1039                 return FALSE;
1040
1041         Length = String1->Length;
1042         pc1 = String1->Buffer;
1043         pc2 = String2->Buffer;
1044
1045         if (pc1 && pc2)
1046         {
1047                 if (CaseInsensitive)
1048                 {
1049                         while (Length--)
1050                         {
1051                                 if (RtlUpperChar (*pc1++) != RtlUpperChar (*pc2++))
1052                                         return FALSE;
1053                         }
1054                 }
1055                 else
1056                 {
1057                         while (Length--)
1058                         {
1059                                 if (*pc1++ != *pc2++)
1060                                         return FALSE;
1061                         }
1062                 }
1063                 return TRUE;
1064         }
1065         return FALSE;
1066 }
1067
1068
1069 BOOLEAN
1070 STDCALL
1071 RtlPrefixUnicodeString (
1072         PUNICODE_STRING String1,
1073         PUNICODE_STRING String2,
1074         BOOLEAN         CaseInsensitive
1075         )
1076 {
1077         PWCHAR pc1;
1078         PWCHAR pc2;
1079         ULONG Length;
1080
1081         if (String2->Length < String1->Length)
1082                 return FALSE;
1083
1084         Length = String1->Length / 2;
1085         pc1 = String1->Buffer;
1086         pc2  = String2->Buffer;
1087
1088         if (pc1 && pc2)
1089         {
1090                 if (CaseInsensitive)
1091                 {
1092                         while (Length--)
1093                         {
1094                                 if (RtlUpcaseUnicodeChar (*pc1++)
1095                                     != RtlUpcaseUnicodeChar (*pc2++))
1096                                         return FALSE;
1097                         }
1098                 }
1099                 else
1100                 {
1101                         while (Length--)
1102                         {
1103                                 if( *pc1++ != *pc2++ )
1104                                         return FALSE;
1105                         }
1106                 }
1107                 return TRUE;
1108         }
1109         return FALSE;
1110 }
1111
1112
1113 ULONG
1114 STDCALL
1115 RtlUnicodeStringToAnsiSize (
1116         IN      PUNICODE_STRING UnicodeString
1117         )
1118 {
1119         ULONG Size;
1120
1121         RtlUnicodeToMultiByteSize (&Size,
1122                                    UnicodeString->Buffer,
1123                                    UnicodeString->Length);
1124
1125         return Size+1; //NB: incl. nullterm
1126 }
1127
1128
1129 NTSTATUS
1130 STDCALL
1131 RtlUnicodeStringToAnsiString (
1132         IN OUT  PANSI_STRING    DestinationString,
1133         IN      PUNICODE_STRING SourceString,
1134         IN      BOOLEAN         AllocateDestinationString
1135         )
1136 {
1137         NTSTATUS Status;
1138         ULONG Length;
1139
1140         if (NlsMbCodePageTag == TRUE)
1141                 Length = RtlUnicodeStringToAnsiSize (SourceString);
1142         else
1143                 Length = SourceString->Length / sizeof(WCHAR);
1144
1145         if (AllocateDestinationString == TRUE)
1146         {
1147                 DestinationString->MaximumLength = Length + sizeof(CHAR);
1148                 DestinationString->Buffer =
1149                         RtlAllocateHeap (RtlGetProcessHeap (),
1150                                          0,
1151                                          DestinationString->MaximumLength);
1152                 if (DestinationString->Buffer == NULL)
1153                         return STATUS_NO_MEMORY;
1154         }
1155         else
1156         {
1157                 if (Length >= DestinationString->MaximumLength)
1158                         return STATUS_BUFFER_TOO_SMALL;
1159         }
1160         DestinationString->Length = Length;
1161
1162         RtlZeroMemory (DestinationString->Buffer,
1163                        DestinationString->Length);
1164
1165         Status = RtlUnicodeToMultiByteN (DestinationString->Buffer,
1166                                          DestinationString->Length,
1167                                          NULL,
1168                                          SourceString->Buffer,
1169                                          SourceString->Length);
1170         if (!NT_SUCCESS(Status))
1171         {
1172                 if (AllocateDestinationString == TRUE)
1173                 {
1174                         RtlFreeHeap (RtlGetProcessHeap (),
1175                                      0,
1176                                      DestinationString->Buffer);
1177                 }
1178                 return Status;
1179         }
1180
1181         DestinationString->Buffer[Length] = 0;
1182
1183         return STATUS_SUCCESS;
1184 }
1185
1186
1187 NTSTATUS
1188 STDCALL
1189 RtlUnicodeStringToInteger (
1190         IN      PUNICODE_STRING String,
1191         IN      ULONG           Base,
1192         OUT     PULONG          Value
1193         )
1194 {
1195         PWCHAR Str;
1196         ULONG lenmin = 0;
1197         ULONG i;
1198         ULONG Val;
1199         BOOLEAN addneg = FALSE;
1200
1201         *Value = 0;
1202         Str = String->Buffer;
1203
1204         for (i = 0; i < String->Length / sizeof(WCHAR); i++)
1205         {
1206                 if (*Str == L'b')
1207                 {
1208                         Base = 2;
1209                         lenmin++;
1210                 }
1211                 else if (*Str == L'o')
1212                 {
1213                         Base = 8;
1214                         lenmin++;
1215                 }
1216                 else if (*Str == L'd')
1217                 {
1218                         Base = 10;
1219                         lenmin++;
1220                 }
1221                 else if (*Str == L'x')
1222                 {
1223                         Base = 16;
1224                         lenmin++;
1225                 }
1226                 else if (*Str == L'+')
1227                 {
1228                         lenmin++;
1229                 }
1230                 else if (*Str == L'-')
1231                 {
1232                         addneg = TRUE;
1233                         lenmin++;
1234                 }
1235                 else if ((*Str > L'1') && (Base == 2))
1236                 {
1237                         return STATUS_INVALID_PARAMETER;
1238                 }
1239                 else if (((*Str > L'7') || (*Str < L'0')) && (Base == 8))
1240                 {
1241                         return STATUS_INVALID_PARAMETER;
1242                 }
1243                 else if (((*Str > L'9') || (*Str < L'0')) && (Base == 10))
1244                 {
1245                         return STATUS_INVALID_PARAMETER;
1246                 }
1247                 else if ((((*Str > L'9') || (*Str < L'0')) ||
1248                           ((towupper (*Str) > L'F') ||
1249                            (towupper (*Str) < L'A'))) && (Base == 16))
1250                 {
1251                         return STATUS_INVALID_PARAMETER;
1252                 }
1253                 else
1254                         Str++;
1255         }
1256
1257         Str = String->Buffer + lenmin;
1258
1259         if (Base == 0)
1260                 Base = 10;
1261
1262         while (iswxdigit (*Str) &&
1263                (Val = iswdigit (*Str) ? *Str - L'0' : (iswlower (*Str)
1264                 ? toupper (*Str) : *Str) - L'A' + 10) < Base)
1265         {
1266                 *Value = *Value * Base + Val;
1267                 Str++;
1268         }
1269
1270         if (addneg == TRUE)
1271                 *Value *= -1;
1272
1273         return STATUS_SUCCESS;
1274 }
1275
1276
1277 ULONG
1278 STDCALL
1279 RtlUnicodeStringToOemSize (
1280         IN      PUNICODE_STRING UnicodeString
1281         )
1282 {
1283         ULONG Size;
1284
1285         RtlUnicodeToMultiByteSize (&Size,
1286                                    UnicodeString->Buffer,
1287                                    UnicodeString->Length);
1288
1289         return Size+1; //NB: incl. nullterm
1290 }
1291
1292
1293 NTSTATUS
1294 STDCALL
1295 RtlUnicodeStringToCountedOemString (
1296         IN OUT  POEM_STRING     DestinationString,
1297         IN      PUNICODE_STRING SourceString,
1298         IN      BOOLEAN         AllocateDestinationString
1299         )
1300 {
1301         NTSTATUS Status;
1302         ULONG Length;
1303         ULONG Size;
1304
1305         if (NlsMbOemCodePageTag == TRUE)
1306                 Length = RtlUnicodeStringToAnsiSize (SourceString)/* + 1*/;
1307         else
1308                 Length = SourceString->Length / sizeof(WCHAR) + 1;
1309
1310         if (Length > 0x0000FFFF)
1311                 return STATUS_INVALID_PARAMETER_2;
1312
1313         DestinationString->Length = (WORD)(Length - 1);
1314
1315         if (AllocateDestinationString)
1316         {
1317                 DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
1318                                                              0,
1319                                                              Length);
1320                 if (DestinationString->Buffer == NULL)
1321                         return STATUS_NO_MEMORY;
1322
1323                 RtlZeroMemory (DestinationString->Buffer,
1324                                Length);
1325                 DestinationString->MaximumLength = (WORD)Length;
1326         }
1327         else
1328         {
1329                 if (Length > DestinationString->MaximumLength)
1330                 {
1331                         if (DestinationString->MaximumLength == 0)
1332                                 return STATUS_BUFFER_OVERFLOW;
1333                         DestinationString->Length =
1334                                 DestinationString->MaximumLength - 1;
1335                 }
1336         }
1337
1338         Status = RtlUnicodeToOemN (DestinationString->Buffer,
1339                                    DestinationString->Length,
1340                                    &Size,
1341                                    SourceString->Buffer,
1342                                    SourceString->Length);
1343         if (!NT_SUCCESS(Status))
1344         {
1345                 if (AllocateDestinationString)
1346                 {
1347                         RtlFreeHeap (RtlGetProcessHeap (),
1348                                      0,
1349                                      DestinationString->Buffer);
1350                 }
1351                 return Status;
1352         }
1353
1354         DestinationString->Buffer[Size] = 0;
1355
1356         return STATUS_SUCCESS;
1357 }
1358
1359
1360 NTSTATUS
1361 STDCALL
1362 RtlUnicodeStringToOemString (
1363         IN OUT  POEM_STRING     DestinationString,
1364         IN      PUNICODE_STRING SourceString,
1365         IN      BOOLEAN         AllocateDestinationString
1366         )
1367 {
1368         NTSTATUS Status;
1369         ULONG Length;
1370         ULONG Size;
1371
1372         if (NlsMbOemCodePageTag == TRUE)
1373                 Length = RtlUnicodeStringToAnsiSize (SourceString)/* + 1*/;
1374         else
1375                 Length = SourceString->Length / sizeof(WCHAR) + 1;
1376
1377         if (Length > 0x0000FFFF)
1378                 return STATUS_INVALID_PARAMETER_2;
1379
1380         DestinationString->Length = (WORD)(Length - 1);
1381
1382         if (AllocateDestinationString)
1383         {
1384                 DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
1385                                                              0,
1386                                                              Length);
1387                 if (DestinationString->Buffer == NULL)
1388                         return STATUS_NO_MEMORY;
1389
1390                 RtlZeroMemory (DestinationString->Buffer,
1391                                Length);
1392                 DestinationString->MaximumLength = (WORD)Length;
1393         }
1394         else
1395         {
1396                 if (Length > DestinationString->MaximumLength)
1397                 {
1398                         if (DestinationString->MaximumLength == 0)
1399                                 return STATUS_BUFFER_OVERFLOW;
1400                         DestinationString->Length =
1401                                 DestinationString->MaximumLength - 1;
1402                 }
1403         }
1404
1405         Status = RtlUnicodeToOemN (DestinationString->Buffer,
1406                                    DestinationString->Length,
1407                                    &Size,
1408                                    SourceString->Buffer,
1409                                    SourceString->Length);
1410         if (!NT_SUCCESS(Status))
1411         {
1412                 if (AllocateDestinationString)
1413                 {
1414                         RtlFreeHeap (RtlGetProcessHeap (),
1415                                      0,
1416                                      DestinationString->Buffer);
1417                 }
1418                 return Status;
1419         }
1420
1421         DestinationString->Buffer[Size] = 0;
1422
1423         return STATUS_SUCCESS;
1424 }
1425
1426
1427 WCHAR
1428 STDCALL
1429 RtlUpcaseUnicodeChar (
1430         IN      WCHAR   Source
1431         )
1432 {
1433         if (Source < L'a')
1434                 return Source;
1435
1436         if (Source <= L'z')
1437                 return (Source - (L'a' - L'A'));
1438
1439         /* FIXME: characters above 'z' */
1440
1441         return Source;
1442 }
1443
1444
1445 NTSTATUS
1446 STDCALL
1447 RtlUpcaseUnicodeString (
1448         IN OUT  PUNICODE_STRING DestinationString,
1449         IN      PUNICODE_STRING SourceString,
1450         IN      BOOLEAN         AllocateDestinationString
1451         )
1452 {
1453         ULONG i;
1454         PWCHAR Src, Dest;
1455
1456         if (AllocateDestinationString == TRUE)
1457         {
1458                 DestinationString->MaximumLength=SourceString->Length+sizeof(WCHAR);
1459                 DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
1460                                                              0,
1461                                                              SourceString->Length + sizeof(WCHAR));
1462                 if (DestinationString->Buffer == NULL)
1463                         return STATUS_NO_MEMORY;
1464         }
1465         else
1466         {
1467                 if (SourceString->Length >= DestinationString->MaximumLength)
1468                         return STATUS_BUFFER_TOO_SMALL;
1469         }
1470         DestinationString->Length = SourceString->Length;
1471
1472         Src = SourceString->Buffer;
1473         Dest = DestinationString->Buffer;
1474         for (i = 0; i < SourceString->Length / sizeof(WCHAR); i++)
1475         {
1476                 *Dest = RtlUpcaseUnicodeChar (*Src);
1477                 Dest++;
1478                 Src++;
1479         }
1480         *Dest = 0;
1481
1482         return STATUS_SUCCESS;
1483 }
1484
1485
1486 NTSTATUS
1487 STDCALL
1488 RtlUpcaseUnicodeStringToAnsiString (
1489         IN OUT  PANSI_STRING    DestinationString,
1490         IN      PUNICODE_STRING SourceString,
1491         IN      BOOLEAN         AllocateDestinationString
1492         )
1493 {
1494         NTSTATUS Status;
1495         ULONG Length;
1496         ULONG Size;
1497
1498         if (NlsMbCodePageTag == TRUE)
1499                 Length = RtlUnicodeStringToAnsiSize (SourceString)/* + 1*/;
1500         else
1501                 Length = SourceString->Length / sizeof(WCHAR) + 1;
1502
1503         if (Length > 0x0000FFFF)
1504                 return STATUS_INVALID_PARAMETER_2;
1505
1506         DestinationString->Length = (WORD)(Length - 1);
1507
1508         if (AllocateDestinationString == TRUE)
1509         {
1510                 DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
1511                                                              0,
1512                                                              DestinationString->MaximumLength);
1513                 if (DestinationString->Buffer == NULL)
1514                         return STATUS_NO_MEMORY;
1515
1516                 RtlZeroMemory (DestinationString->Buffer,
1517                                Length);
1518                 DestinationString->MaximumLength = (WORD)Length;
1519         }
1520         else
1521         {
1522                 if (Length > DestinationString->MaximumLength)
1523                 {
1524                         if (!DestinationString->MaximumLength)
1525                                 return STATUS_BUFFER_OVERFLOW;
1526                         DestinationString->Length =
1527                                 DestinationString->MaximumLength - 1;
1528                 }
1529         }
1530
1531         Status = RtlUpcaseUnicodeToMultiByteN (DestinationString->Buffer,
1532                                                DestinationString->Length,
1533                                                &Size,
1534                                                SourceString->Buffer,
1535                                                SourceString->Length);
1536         if (!NT_SUCCESS(Status))
1537         {
1538                 if (AllocateDestinationString)
1539                 {
1540                         RtlFreeHeap (RtlGetProcessHeap (),
1541                                      0,
1542                                      DestinationString->Buffer);
1543                 }
1544                 return Status;
1545         }
1546
1547         DestinationString->Buffer[Size] = 0;
1548
1549         return STATUS_SUCCESS;
1550 }
1551
1552
1553 NTSTATUS
1554 STDCALL
1555 RtlUpcaseUnicodeStringToCountedOemString (
1556         IN OUT  POEM_STRING     DestinationString,
1557         IN      PUNICODE_STRING SourceString,
1558         IN      BOOLEAN         AllocateDestinationString
1559         )
1560 {
1561         NTSTATUS Status;
1562         ULONG Length;
1563         ULONG Size;
1564
1565         if (NlsMbCodePageTag == TRUE)
1566                 Length = RtlUnicodeStringToAnsiSize (SourceString)/* + 1*/;
1567         else
1568                 Length = SourceString->Length / sizeof(WCHAR) + 1;
1569
1570         if (Length > 0x0000FFFF)
1571                 return STATUS_INVALID_PARAMETER_2;
1572
1573         DestinationString->Length = (WORD)(Length - 1);
1574
1575         if (AllocateDestinationString == TRUE)
1576         {
1577                 DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
1578                                                              0,
1579                                                              Length);
1580                 if (DestinationString->Buffer == NULL)
1581                         return STATUS_NO_MEMORY;
1582
1583                 RtlZeroMemory (DestinationString->Buffer,
1584                                Length);
1585                 DestinationString->MaximumLength = (WORD)Length;
1586         }
1587         else
1588         {
1589                 if (Length > DestinationString->MaximumLength)
1590                 {
1591                         if (DestinationString->MaximumLength == 0)
1592                                 return STATUS_BUFFER_OVERFLOW;
1593                         DestinationString->Length =
1594                                 DestinationString->MaximumLength - 1;
1595                 }
1596         }
1597
1598         Status = RtlUpcaseUnicodeToOemN (DestinationString->Buffer,
1599                                          DestinationString->Length,
1600                                          &Size,
1601                                          SourceString->Buffer,
1602                                          SourceString->Length);
1603         if (!NT_SUCCESS(Status))
1604         {
1605                 if (AllocateDestinationString)
1606                 {
1607                         RtlFreeHeap (RtlGetProcessHeap (),
1608                                      0,
1609                                      DestinationString->Buffer);
1610                 }
1611                 return Status;
1612         }
1613
1614         DestinationString->Buffer[Size] = 0;
1615
1616         return STATUS_SUCCESS;
1617 }
1618
1619
1620 NTSTATUS
1621 STDCALL
1622 RtlUpcaseUnicodeStringToOemString (
1623         IN OUT  POEM_STRING     DestinationString,
1624         IN      PUNICODE_STRING SourceString,
1625         IN      BOOLEAN         AllocateDestinationString
1626         )
1627 {
1628         NTSTATUS Status;
1629         ULONG Length;
1630         ULONG Size;
1631
1632         if (NlsMbOemCodePageTag == TRUE)
1633                 Length = RtlUnicodeStringToAnsiSize (SourceString)/* + 1*/;
1634         else
1635                 Length = SourceString->Length / sizeof(WCHAR) + 1;
1636
1637         if (Length > 0x0000FFFF)
1638                 return STATUS_INVALID_PARAMETER_2;
1639
1640         DestinationString->Length = (WORD)(Length - 1);
1641
1642         if (AllocateDestinationString == TRUE)
1643         {
1644                 DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
1645                                                              0,
1646                                                              Length);
1647                 if (DestinationString->Buffer == NULL)
1648                         return STATUS_NO_MEMORY;
1649
1650                 RtlZeroMemory (DestinationString->Buffer,
1651                                Length);
1652                 DestinationString->MaximumLength = (WORD)Length;
1653         }
1654         else
1655         {
1656                 if (Length > DestinationString->MaximumLength)
1657                 {
1658                         if (DestinationString->MaximumLength == 0)
1659                                 return STATUS_BUFFER_OVERFLOW;
1660                         DestinationString->Length =
1661                                 DestinationString->MaximumLength - 1;
1662                 }
1663         }
1664
1665         Status = RtlUpcaseUnicodeToOemN (DestinationString->Buffer,
1666                                          DestinationString->Length,
1667                                          &Size,
1668                                          SourceString->Buffer,
1669                                          SourceString->Length);
1670         if (!NT_SUCCESS(Status))
1671         {
1672                 if (AllocateDestinationString)
1673                 {
1674                         RtlFreeHeap (RtlGetProcessHeap (),
1675                                      0,
1676                                      DestinationString->Buffer);
1677                 }
1678                 return Status;
1679         }
1680
1681         DestinationString->Buffer[Size] = 0;
1682
1683         return STATUS_SUCCESS;
1684 }
1685
1686
1687 CHAR
1688 STDCALL
1689 RtlUpperChar (
1690         IN      CHAR    Source
1691         )
1692 {
1693         WCHAR   Unicode;
1694         CHAR    Destination;
1695
1696         if (NlsMbCodePageTag == FALSE)
1697         {
1698                 /* single-byte code page */
1699                 /* ansi->unicode */
1700                 Unicode = (WCHAR)Source;
1701 #if 0
1702                 Unicode = NlsAnsiToUnicodeData[Source];
1703 #endif
1704
1705                 /* upcase conversion */
1706                 Unicode = RtlUpcaseUnicodeChar (Unicode);
1707
1708                 /* unicode -> ansi */
1709                 Destination = (CHAR)Unicode;
1710 #if 0
1711                 Destination = NlsUnicodeToAnsiData[Unicode];
1712 #endif
1713         }
1714         else
1715         {
1716                 /* single-byte code page */
1717                 /* FIXME: implement the multi-byte stuff!! */
1718                 Destination = Source;
1719         }
1720
1721         return Destination;
1722 }
1723
1724
1725 VOID
1726 STDCALL
1727 RtlUpperString (
1728         IN OUT  PSTRING DestinationString,
1729         IN      PSTRING SourceString
1730         )
1731 {
1732         ULONG Length;
1733         ULONG i;
1734         PCHAR Src;
1735         PCHAR Dest;
1736
1737         Length = min(SourceString->Length, DestinationString->MaximumLength - 1);
1738
1739         Src = SourceString->Buffer;
1740         Dest = DestinationString->Buffer;
1741         for (i = 0; i < Length; i++)
1742         {
1743                 *Dest = RtlUpperChar (*Src);
1744                 Src++;
1745                 Dest++;
1746         }
1747         *Dest = 0;
1748
1749         DestinationString->Length = SourceString->Length;
1750 }
1751
1752
1753 ULONG
1754 STDCALL
1755 RtlxAnsiStringToUnicodeSize (
1756         IN      PANSI_STRING    AnsiString
1757         )
1758 {
1759         return RtlAnsiStringToUnicodeSize (AnsiString);
1760 }
1761
1762
1763 ULONG
1764 STDCALL
1765 RtlxOemStringToUnicodeSize (
1766         IN      POEM_STRING     OemString
1767         )
1768 {
1769         return RtlAnsiStringToUnicodeSize ((PANSI_STRING)OemString);
1770 }
1771
1772
1773 ULONG
1774 STDCALL
1775 RtlxUnicodeStringToAnsiSize (
1776         IN      PUNICODE_STRING UnicodeString
1777         )
1778 {
1779         return RtlUnicodeStringToAnsiSize (UnicodeString);
1780 }
1781
1782
1783 ULONG
1784 STDCALL
1785 RtlxUnicodeStringToOemSize (
1786         IN      PUNICODE_STRING UnicodeString
1787         )
1788 {
1789         return RtlUnicodeStringToAnsiSize (UnicodeString);
1790 }
1791
1792 /* EOF */