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