4 * Copyright (C) 1996-1998 Marcus Meissner
5 * Copyright (C) 2000 Alexandre Julliard
6 * Copyright (C) 2003 Thomas Mertes
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 /* GLOBALS *******************************************************************/
30 extern BOOLEAN NlsMbCodePageTag
;
31 extern BOOLEAN NlsMbOemCodePageTag
;
33 /* FUNCTIONS *****************************************************************/
40 RtlAnsiCharToUnicodeChar (IN CHAR AnsiChar
)
48 Size
= (NlsLeadByteInfo
[AnsiChar
] == 0) ? 1 : 2;
51 RtlMultiByteToUnicodeN (&UnicodeChar
,
65 * The calculated size in bytes including nullterm.
69 RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString
)
73 RtlMultiByteToUnicodeSize(&Size
,
86 * If src->length is zero dest is unchanged.
87 * Dest is never nullterminated.
91 RtlAppendStringToString(IN OUT PSTRING Destination
,
96 if (Source
->Length
== 0)
97 return(STATUS_SUCCESS
);
99 if (Destination
->Length
+ Source
->Length
>= Destination
->MaximumLength
)
100 return(STATUS_BUFFER_TOO_SMALL
);
102 Ptr
= Destination
->Buffer
+ Destination
->Length
;
106 Ptr
+= Source
->Length
;
109 Destination
->Length
+= Source
->Length
;
111 return(STATUS_SUCCESS
);
120 * If src->length is zero dest is unchanged.
121 * Dest is nullterminated when the MaximumLength allowes it.
122 * When dest fits exactly in MaximumLength characters the nullterm is ommitted.
126 RtlAppendUnicodeStringToString(
127 IN OUT PUNICODE_STRING Destination
,
128 IN PUNICODE_STRING Source
)
131 if ((Source
->Length
+ Destination
->Length
) > Destination
->MaximumLength
)
132 return STATUS_BUFFER_TOO_SMALL
;
134 memcpy((char*)Destination
->Buffer
+ Destination
->Length
, Source
->Buffer
, Source
->Length
);
135 Destination
->Length
+= Source
->Length
;
136 /* append terminating '\0' if enough space */
137 if( Destination
->MaximumLength
> Destination
->Length
)
138 Destination
->Buffer
[Destination
->Length
/ sizeof(WCHAR
)] = 0;
140 return STATUS_SUCCESS
;
144 /**************************************************************************
145 * RtlCharToInteger (NTDLL.@)
147 * Converts a character string into its integer equivalent.
150 * Success: STATUS_SUCCESS. value contains the converted number
151 * Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
152 * STATUS_ACCESS_VIOLATION, if value is NULL.
155 * For base 0 it uses 10 as base and the string should be in the format
156 * "{whitespace} [+|-] [0[x|o|b]] {digits}".
157 * For other bases the string should be in the format
158 * "{whitespace} [+|-] {digits}".
159 * No check is made for value overflow, only the lower 32 bits are assigned.
160 * If str is NULL it crashes, as the native function does.
163 * This function does not read garbage behind '\0' as the native version does.
168 PCSZ str
, /* [I] '\0' terminated single-byte string containing a number */
169 ULONG base
, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
170 PULONG value
) /* [O] Destination for the converted value */
174 ULONG RunningTotal
= 0;
177 while (*str
!= '\0' && *str
<= ' ') {
183 } else if (*str
== '-') {
194 } else if (str
[1] == 'o') {
197 } else if (str
[1] == 'x') {
202 } else if (base
!= 2 && base
!= 8 && base
!= 10 && base
!= 16) {
203 return STATUS_INVALID_PARAMETER
;
207 return STATUS_ACCESS_VIOLATION
;
210 while (*str
!= '\0') {
212 if (chCurrent
>= '0' && chCurrent
<= '9') {
213 digit
= chCurrent
- '0';
214 } else if (chCurrent
>= 'A' && chCurrent
<= 'Z') {
215 digit
= chCurrent
- 'A' + 10;
216 } else if (chCurrent
>= 'a' && chCurrent
<= 'z') {
217 digit
= chCurrent
- 'a' + 10;
221 if (digit
< 0 || digit
>= (int)base
) {
222 *value
= bMinus
? -RunningTotal
: RunningTotal
;
223 return STATUS_SUCCESS
;
226 RunningTotal
= RunningTotal
* base
+ digit
;
230 *value
= bMinus
? -RunningTotal
: RunningTotal
;
231 return STATUS_SUCCESS
;
242 IN BOOLEAN CaseInsensitive
)
248 if (String1
&& String2
)
250 len1
= String1
->Length
;
251 len2
= String2
->Length
;
252 s1
= String1
->Buffer
;
253 s2
= String2
->Buffer
;
261 c1
= len1
-- ? RtlUpperChar (*s1
++) : 0;
262 c2
= len2
-- ? RtlUpperChar (*s2
++) : 0;
263 if (!c1
|| !c2
|| c1
!= c2
)
271 c1
= len1
-- ? *s1
++ : 0;
272 c2
= len2
-- ? *s2
++ : 0;
273 if (!c1
|| !c2
|| c1
!= c2
)
288 * TRUE if strings are equal.
295 IN BOOLEAN CaseInsensitive
)
301 if (String1
->Length
!= String2
->Length
)
304 p1
= String1
->Buffer
;
305 p2
= String2
->Buffer
;
306 for (i
= 0; i
< String1
->Length
; i
++)
308 if (CaseInsensitive
== TRUE
)
310 c1
= RtlUpperChar (*p1
);
311 c2
= RtlUpperChar (*p2
);
334 * TRUE if strings are equal.
338 RtlEqualUnicodeString(
339 IN CONST UNICODE_STRING
*String1
,
340 IN CONST UNICODE_STRING
*String2
,
341 IN BOOLEAN CaseInsensitive
)
347 if (String1
->Length
!= String2
->Length
)
350 pw1
= String1
->Buffer
;
351 pw2
= String2
->Buffer
;
353 for (i
= 0; i
< String1
->Length
/ sizeof(WCHAR
); i
++)
355 if (CaseInsensitive
== TRUE
)
357 wc1
= RtlUpcaseUnicodeChar (*pw1
);
358 wc2
= RtlUpcaseUnicodeChar (*pw2
);
382 RtlFreeAnsiString(IN PANSI_STRING AnsiString
)
384 if (AnsiString
->Buffer
!= NULL
)
386 RtlpFreeStringMemory(AnsiString
->Buffer
, TAG_ASTR
);
388 AnsiString
->Buffer
= NULL
;
389 AnsiString
->Length
= 0;
390 AnsiString
->MaximumLength
= 0;
400 RtlFreeOemString(IN POEM_STRING OemString
)
402 if (OemString
->Buffer
!= NULL
)
404 RtlpFreeStringMemory(OemString
->Buffer
, TAG_OSTR
);
406 OemString
->Buffer
= NULL
;
407 OemString
->Length
= 0;
408 OemString
->MaximumLength
= 0;
418 RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString
)
420 if (UnicodeString
->Buffer
!= NULL
)
422 RtlpFreeStringMemory(UnicodeString
->Buffer
, TAG_USTR
);
424 UnicodeString
->Buffer
= NULL
;
425 UnicodeString
->Length
= 0;
426 UnicodeString
->MaximumLength
= 0;
435 RtlIsValidOemCharacter (
447 * If source is NULL the length of source is assumed to be 0.
451 RtlInitAnsiString(IN OUT PANSI_STRING DestinationString
,
452 IN PCSZ SourceString
)
456 if (SourceString
== NULL
)
458 DestinationString
->Length
= 0;
459 DestinationString
->MaximumLength
= 0;
463 DestSize
= strlen ((const char *)SourceString
);
464 DestinationString
->Length
= DestSize
;
465 DestinationString
->MaximumLength
= DestSize
+ sizeof(CHAR
);
467 DestinationString
->Buffer
= (PCHAR
)SourceString
;
476 * If source is NULL the length of source is assumed to be 0.
481 IN OUT PSTRING DestinationString
,
482 IN PCSZ SourceString
)
486 if (SourceString
== NULL
)
488 DestinationString
->Length
= 0;
489 DestinationString
->MaximumLength
= 0;
493 DestSize
= strlen((const char *)SourceString
);
494 DestinationString
->Length
= DestSize
;
495 DestinationString
->MaximumLength
= DestSize
+ sizeof(CHAR
);
497 DestinationString
->Buffer
= (PCHAR
)SourceString
;
505 * If source is NULL the length of source is assumed to be 0.
509 RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
510 IN PCWSTR SourceString
)
514 DPRINT("RtlInitUnicodeString(DestinationString 0x%p, SourceString 0x%p)\n",
518 if (SourceString
== NULL
)
520 DestinationString
->Length
= 0;
521 DestinationString
->MaximumLength
= 0;
525 DestSize
= wcslen((PWSTR
)SourceString
) * sizeof(WCHAR
);
526 DestinationString
->Length
= DestSize
;
527 DestinationString
->MaximumLength
= DestSize
+ sizeof(WCHAR
);
529 DestinationString
->Buffer
= (PWSTR
)SourceString
;
536 RtlInitUnicodeStringEx(OUT PUNICODE_STRING DestinationString
,
537 IN PCWSTR SourceString
)
541 if (SourceString
!= NULL
)
543 Length
= wcslen(SourceString
) * sizeof(WCHAR
);
545 return STATUS_NAME_TOO_LONG
;
547 DestinationString
->Length
= Length
;
548 DestinationString
->MaximumLength
= Length
+ sizeof(WCHAR
);
549 DestinationString
->Buffer
= (PWSTR
)SourceString
;
553 DestinationString
->Length
= 0;
554 DestinationString
->MaximumLength
= 0;
555 DestinationString
->Buffer
= NULL
;
558 return STATUS_SUCCESS
;
565 * Writes at most length characters to the string str.
566 * Str is nullterminated when length allowes it.
567 * When str fits exactly in length characters the nullterm is ommitted.
588 if ((Radix
!= 2) && (Radix
!= 8) &&
589 (Radix
!= 10) && (Radix
!= 16))
591 return STATUS_INVALID_PARAMETER
;
595 while (v
|| tp
== temp
)
606 if ((ULONG
)((ULONG_PTR
)tp
- (ULONG_PTR
)temp
) >= Length
)
608 return STATUS_BUFFER_TOO_SMALL
;
616 return STATUS_SUCCESS
;
627 IN ULONG Base OPTIONAL
,
628 IN ULONG Length OPTIONAL
,
643 if ((Radix
!= 2) && (Radix
!= 8) &&
644 (Radix
!= 10) && (Radix
!= 16))
646 return STATUS_INVALID_PARAMETER
;
650 while (v
|| tp
== temp
)
661 if ((ULONG
)((ULONG_PTR
)tp
- (ULONG_PTR
)temp
) >= Length
)
663 return STATUS_BUFFER_TOO_SMALL
;
671 return STATUS_SUCCESS
;
681 RtlIntegerToUnicodeString(
683 IN ULONG Base
, /* optional */
684 IN OUT PUNICODE_STRING String
)
686 ANSI_STRING AnsiString
;
690 Status
= RtlIntegerToChar (Value
,
694 if (NT_SUCCESS(Status
))
696 AnsiString
.Buffer
= Buffer
;
697 AnsiString
.Length
= strlen (Buffer
);
698 AnsiString
.MaximumLength
= sizeof(Buffer
);
700 Status
= RtlAnsiStringToUnicodeString (String
,
714 RtlInt64ToUnicodeString (
716 IN ULONG Base OPTIONAL
,
717 IN OUT PUNICODE_STRING String
720 LARGE_INTEGER LargeInt
;
721 ANSI_STRING AnsiString
;
725 LargeInt
.QuadPart
= Value
;
727 Status
= RtlLargeIntegerToChar (&LargeInt
,
731 if (NT_SUCCESS(Status
))
733 AnsiString
.Buffer
= Buffer
;
734 AnsiString
.Length
= strlen (Buffer
);
735 AnsiString
.MaximumLength
= sizeof(Buffer
);
737 Status
= RtlAnsiStringToUnicodeString (String
,
750 * TRUE if String2 contains String1 as a prefix.
755 PANSI_STRING String1
,
756 PANSI_STRING String2
,
757 BOOLEAN CaseInsensitive
)
763 if (String2
->Length
< String1
->Length
)
766 Length
= String1
->Length
;
767 pc1
= String1
->Buffer
;
768 pc2
= String2
->Buffer
;
776 if (RtlUpperChar (*pc1
++) != RtlUpperChar (*pc2
++))
784 if (*pc1
++ != *pc2
++)
798 * TRUE if String2 contains String1 as a prefix.
802 RtlPrefixUnicodeString(
803 PUNICODE_STRING String1
,
804 PUNICODE_STRING String2
,
805 BOOLEAN CaseInsensitive
)
811 if (String2
->Length
< String1
->Length
)
814 Length
= String1
->Length
/ 2;
815 pc1
= String1
->Buffer
;
816 pc2
= String2
->Buffer
;
824 if (RtlUpcaseUnicodeChar (*pc1
++)
825 != RtlUpcaseUnicodeChar (*pc2
++))
833 if( *pc1
++ != *pc2
++ )
842 /**************************************************************************
843 * RtlUnicodeStringToInteger (NTDLL.@)
845 * Converts an unicode string into its integer equivalent.
848 * Success: STATUS_SUCCESS. value contains the converted number
849 * Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
850 * STATUS_ACCESS_VIOLATION, if value is NULL.
853 * For base 0 it uses 10 as base and the string should be in the format
854 * "{whitespace} [+|-] [0[x|o|b]] {digits}".
855 * For other bases the string should be in the format
856 * "{whitespace} [+|-] {digits}".
857 * No check is made for value overflow, only the lower 32 bits are assigned.
858 * If str is NULL it crashes, as the native function does.
860 * Note that regardless of success or failure status, we should leave the
861 * partial value in Value. An error is never returned based on the chars
865 * This function does not read garbage on string length 0 as the native
870 RtlUnicodeStringToInteger(
871 PUNICODE_STRING str
, /* [I] Unicode string to be converted */
872 ULONG base
, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
873 PULONG value
) /* [O] Destination for the converted value */
875 LPWSTR lpwstr
= str
->Buffer
;
876 USHORT CharsRemaining
= str
->Length
/ sizeof(WCHAR
);
879 ULONG RunningTotal
= 0;
882 while (CharsRemaining
>= 1 && *lpwstr
<= ' ') {
887 if (CharsRemaining
>= 1) {
888 if (*lpwstr
== '+') {
891 } else if (*lpwstr
== '-') {
900 if (CharsRemaining
>= 2 && lpwstr
[0] == '0') {
901 if (lpwstr
[1] == 'b') {
905 } else if (lpwstr
[1] == 'o') {
909 } else if (lpwstr
[1] == 'x') {
915 } else if (base
!= 2 && base
!= 8 && base
!= 10 && base
!= 16) {
916 return STATUS_INVALID_PARAMETER
;
920 return STATUS_ACCESS_VIOLATION
;
923 while (CharsRemaining
>= 1) {
924 wchCurrent
= *lpwstr
;
925 if (wchCurrent
>= '0' && wchCurrent
<= '9') {
926 digit
= wchCurrent
- '0';
927 } else if (wchCurrent
>= 'A' && wchCurrent
<= 'Z') {
928 digit
= wchCurrent
- 'A' + 10;
929 } else if (wchCurrent
>= 'a' && wchCurrent
<= 'z') {
930 digit
= wchCurrent
- 'a' + 10;
934 if (digit
< 0 || digit
>= (int)base
) {
935 *value
= bMinus
? -RunningTotal
: RunningTotal
;
936 return STATUS_SUCCESS
;
939 RunningTotal
= RunningTotal
* base
+ digit
;
944 *value
= bMinus
? -RunningTotal
: RunningTotal
;
945 return STATUS_SUCCESS
;
953 * Bytes necessary for the conversion including nullterm.
957 RtlUnicodeStringToOemSize(
958 IN PUNICODE_STRING UnicodeString
)
962 RtlUnicodeToMultiByteSize (&Size
,
963 UnicodeString
->Buffer
,
964 UnicodeString
->Length
);
966 return Size
+1; //NB: incl. nullterm
974 * This function always writes a terminating '\0'.
975 * It performs a partial copy if ansi is too small.
979 RtlUnicodeStringToAnsiString(
980 IN OUT PANSI_STRING AnsiDest
,
981 IN PUNICODE_STRING UniSource
,
982 IN BOOLEAN AllocateDestinationString
)
984 NTSTATUS Status
= STATUS_SUCCESS
;
985 ULONG Length
; /* including nullterm */
987 if (NlsMbCodePageTag
== TRUE
)
989 Length
= RtlUnicodeStringToAnsiSize(UniSource
);
992 Length
= (UniSource
->Length
/ sizeof(WCHAR
)) + sizeof(CHAR
);
994 AnsiDest
->Length
= Length
- sizeof(CHAR
);
996 if (AllocateDestinationString
)
998 AnsiDest
->Buffer
= RtlpAllocateStringMemory(Length
, TAG_ASTR
);
999 if (AnsiDest
->Buffer
== NULL
)
1000 return STATUS_NO_MEMORY
;
1002 AnsiDest
->MaximumLength
= Length
;
1004 else if (AnsiDest
->MaximumLength
== 0)
1006 return STATUS_BUFFER_TOO_SMALL
;
1008 else if (Length
> AnsiDest
->MaximumLength
)
1010 /* make room for nullterm */
1011 AnsiDest
->Length
= AnsiDest
->MaximumLength
- sizeof(CHAR
);
1014 Status
= RtlUnicodeToMultiByteN (AnsiDest
->Buffer
,
1020 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
1022 RtlpFreeStringMemory(AnsiDest
->Buffer
, TAG_ASTR
);
1026 AnsiDest
->Buffer
[AnsiDest
->Length
] = 0;
1035 * This function always writes a terminating '\0'.
1036 * Does NOT perform a partial copy if unicode is too small!
1040 RtlOemStringToUnicodeString(
1041 IN OUT PUNICODE_STRING UniDest
,
1042 IN POEM_STRING OemSource
,
1043 IN BOOLEAN AllocateDestinationString
)
1046 ULONG Length
; /* including nullterm */
1048 if (NlsMbOemCodePageTag
== TRUE
)
1049 Length
= RtlOemStringToUnicodeSize(OemSource
);
1051 Length
= (OemSource
->Length
* sizeof(WCHAR
)) + sizeof(WCHAR
);
1053 if (Length
> 0xffff)
1054 return STATUS_INVALID_PARAMETER_2
;
1056 UniDest
->Length
= (WORD
)(Length
- sizeof(WCHAR
));
1058 if (AllocateDestinationString
)
1060 UniDest
->Buffer
= RtlpAllocateStringMemory(Length
, TAG_USTR
);
1061 if (UniDest
->Buffer
== NULL
)
1062 return STATUS_NO_MEMORY
;
1064 UniDest
->MaximumLength
= Length
;
1066 else if (Length
> UniDest
->MaximumLength
)
1068 DPRINT("STATUS_BUFFER_TOO_SMALL\n");
1069 return STATUS_BUFFER_TOO_SMALL
;
1072 /* FIXME: Do we need this????? -Gunnar */
1073 RtlZeroMemory (UniDest
->Buffer
,
1076 Status
= RtlOemToUnicodeN (UniDest
->Buffer
,
1082 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
1084 RtlpFreeStringMemory(UniDest
->Buffer
, TAG_USTR
);
1088 UniDest
->Buffer
[UniDest
->Length
/ sizeof(WCHAR
)] = 0;
1089 return STATUS_SUCCESS
;
1097 * This function always '\0' terminates the string returned.
1101 RtlUnicodeStringToOemString(
1102 IN OUT POEM_STRING OemDest
,
1103 IN PUNICODE_STRING UniSource
,
1104 IN BOOLEAN AllocateDestinationString
)
1106 NTSTATUS Status
= STATUS_SUCCESS
;
1107 ULONG Length
; //including nullterm
1109 if (NlsMbOemCodePageTag
== TRUE
)
1110 Length
= RtlUnicodeStringToAnsiSize (UniSource
);
1112 Length
= (UniSource
->Length
/ sizeof(WCHAR
)) + sizeof(CHAR
);
1114 if (Length
> 0x0000FFFF)
1115 return STATUS_INVALID_PARAMETER_2
;
1117 OemDest
->Length
= (WORD
)(Length
- sizeof(CHAR
));
1119 if (AllocateDestinationString
)
1121 OemDest
->Buffer
= RtlpAllocateStringMemory(Length
, TAG_OSTR
);
1122 if (OemDest
->Buffer
== NULL
)
1123 return STATUS_NO_MEMORY
;
1125 OemDest
->MaximumLength
= Length
;
1127 else if (OemDest
->MaximumLength
== 0)
1129 return STATUS_BUFFER_TOO_SMALL
;
1131 else if (Length
> OemDest
->MaximumLength
)
1133 //make room for nullterm
1134 OemDest
->Length
= OemDest
->MaximumLength
- sizeof(CHAR
);
1137 Status
= RtlUnicodeToOemN (OemDest
->Buffer
,
1143 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
1145 RtlpFreeStringMemory(OemDest
->Buffer
, TAG_OSTR
);
1149 OemDest
->Buffer
[OemDest
->Length
] = 0;
1153 #define ITU_IMPLEMENTED_TESTS (IS_TEXT_UNICODE_ODD_LENGTH|IS_TEXT_UNICODE_SIGNATURE)
1160 * The length of the string if all tests were passed, 0 otherwise.
1163 RtlIsTextUnicode (PVOID Buffer
,
1168 ULONG in_flags
= (ULONG
)-1;
1169 ULONG out_flags
= 0;
1178 * Apply various tests to the text string. According to the
1179 * docs, each test "passed" sets the corresponding flag in
1180 * the output flags. But some of the tests are mutually
1181 * exclusive, so I don't see how you could pass all tests ...
1184 /* Check for an odd length ... pass if even. */
1186 out_flags
|= IS_TEXT_UNICODE_ODD_LENGTH
;
1188 /* Check for the BOM (byte order mark). */
1190 out_flags
|= IS_TEXT_UNICODE_SIGNATURE
;
1193 /* Check for the reverse BOM (byte order mark). */
1195 out_flags
|= IS_TEXT_UNICODE_REVERSE_SIGNATURE
;
1198 /* FIXME: Add more tests */
1201 * Check whether the string passed all of the tests.
1203 in_flags
&= ITU_IMPLEMENTED_TESTS
;
1204 if ((out_flags
& in_flags
) != in_flags
)
1219 * Same as RtlOemStringToUnicodeString but doesn't write terminating null
1220 * A partial copy is NOT performed if the dest buffer is too small!
1224 RtlOemStringToCountedUnicodeString(
1225 IN OUT PUNICODE_STRING UniDest
,
1226 IN POEM_STRING OemSource
,
1227 IN BOOLEAN AllocateDestinationString
)
1230 ULONG Length
; /* excluding nullterm */
1232 if (NlsMbCodePageTag
== TRUE
)
1233 Length
= RtlOemStringToUnicodeSize(OemSource
) - sizeof(WCHAR
);
1235 Length
= OemSource
->Length
* sizeof(WCHAR
);
1238 return STATUS_INVALID_PARAMETER_2
;
1240 if (AllocateDestinationString
== TRUE
)
1242 UniDest
->Buffer
= RtlpAllocateStringMemory (Length
, TAG_USTR
);
1243 if (UniDest
->Buffer
== NULL
)
1244 return STATUS_NO_MEMORY
;
1246 UniDest
->MaximumLength
= Length
;
1248 else if (Length
> UniDest
->MaximumLength
)
1250 return STATUS_BUFFER_TOO_SMALL
;
1253 UniDest
->Length
= Length
;
1255 Status
= RtlOemToUnicodeN (UniDest
->Buffer
,
1261 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
1263 RtlpFreeStringMemory(UniDest
->Buffer
, TAG_USTR
);
1274 * TRUE if the names are equal, FALSE if not
1277 * The comparison is case insensitive.
1281 RtlEqualComputerName(
1282 IN PUNICODE_STRING ComputerName1
,
1283 IN PUNICODE_STRING ComputerName2
)
1285 OEM_STRING OemString1
;
1286 OEM_STRING OemString2
;
1287 BOOLEAN Result
= FALSE
;
1289 if (NT_SUCCESS(RtlUpcaseUnicodeStringToOemString( &OemString1
, ComputerName1
, TRUE
)))
1291 if (NT_SUCCESS(RtlUpcaseUnicodeStringToOemString( &OemString2
, ComputerName2
, TRUE
)))
1293 Result
= RtlEqualString( &OemString1
, &OemString2
, TRUE
);
1294 RtlFreeOemString( &OemString2
);
1296 RtlFreeOemString( &OemString1
);
1306 * TRUE if the names are equal, FALSE if not
1309 * The comparison is case insensitive.
1313 RtlEqualDomainName (
1314 IN PUNICODE_STRING DomainName1
,
1315 IN PUNICODE_STRING DomainName2
1318 return RtlEqualComputerName(DomainName1
, DomainName2
);
1328 RtlEqualDomainName (
1329 IN PUNICODE_STRING DomainName1,
1330 IN PUNICODE_STRING DomainName2
1333 OEM_STRING OemString1;
1334 OEM_STRING OemString2;
1337 RtlUpcaseUnicodeStringToOemString (&OemString1,
1340 RtlUpcaseUnicodeStringToOemString (&OemString2,
1344 Result = RtlEqualString (&OemString1,
1348 RtlFreeOemString (&OemString1);
1349 RtlFreeOemString (&OemString2);
1359 * RIPPED FROM WINE's ntdll\rtlstr.c rev 1.45
1361 * Convert a string representation of a GUID into a GUID.
1364 * str [I] String representation in the format "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
1365 * guid [O] Destination for the converted GUID
1368 * Success: STATUS_SUCCESS. guid contains the converted value.
1369 * Failure: STATUS_INVALID_PARAMETER, if str is not in the expected format.
1372 * See RtlStringFromGUID.
1377 IN UNICODE_STRING
*str
,
1382 const WCHAR
*lpszCLSID
= str
->Buffer
;
1383 BYTE
* lpOut
= (BYTE
*)guid
;
1385 //TRACE("(%s,%p)\n", debugstr_us(str), guid);
1387 /* Convert string: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
1388 * to memory: DWORD... WORD WORD BYTES............
1395 if (*lpszCLSID
!= '{')
1396 return STATUS_INVALID_PARAMETER
;
1403 if (*lpszCLSID
!= '-')
1404 return STATUS_INVALID_PARAMETER
;
1408 if (*lpszCLSID
!= '}')
1409 return STATUS_INVALID_PARAMETER
;
1414 WCHAR ch
= *lpszCLSID
, ch2
= lpszCLSID
[1];
1417 /* Read two hex digits as a byte value */
1418 if (ch
>= '0' && ch
<= '9')
1420 else if (ch
>= 'a' && ch
<= 'f')
1422 else if (ch
>= 'A' && ch
<= 'F')
1425 return STATUS_INVALID_PARAMETER
;
1427 if (ch2
>= '0' && ch2
<= '9')
1429 else if (ch2
>= 'a' && ch2
<= 'f')
1430 ch2
= ch2
- 'a' + 10;
1431 else if (ch2
>= 'A' && ch2
<= 'F')
1432 ch2
= ch2
- 'A' + 10;
1434 return STATUS_INVALID_PARAMETER
;
1436 byte
= ch
<< 4 | ch2
;
1440 #ifndef WORDS_BIGENDIAN
1441 /* For Big Endian machines, we store the data such that the
1442 * dword/word members can be read as DWORDS and WORDS correctly. */
1474 lpszCLSID
++; /* Skip 2nd character of byte */
1482 return STATUS_SUCCESS
;
1490 RtlEraseUnicodeString(
1491 IN PUNICODE_STRING String
)
1493 if (String
->Buffer
!= NULL
&&
1494 String
->MaximumLength
!= 0)
1496 RtlZeroMemory (String
->Buffer
,
1497 String
->MaximumLength
);
1508 RtlHashUnicodeString(
1509 IN CONST UNICODE_STRING
*String
,
1510 IN BOOLEAN CaseInSensitive
,
1511 IN ULONG HashAlgorithm
,
1512 OUT PULONG HashValue
)
1514 if (String
!= NULL
&& HashValue
!= NULL
)
1516 switch (HashAlgorithm
)
1518 case HASH_STRING_ALGORITHM_DEFAULT
:
1519 case HASH_STRING_ALGORITHM_X65599
:
1524 end
= String
->Buffer
+ (String
->Length
/ sizeof(WCHAR
));
1526 if (CaseInSensitive
)
1528 for (c
= String
->Buffer
;
1532 /* only uppercase characters if they are 'a' ... 'z'! */
1533 *HashValue
= ((65599 * (*HashValue
)) +
1534 (ULONG
)(((*c
) >= L
'a' && (*c
) <= L
'z') ?
1535 (*c
) - L
'a' + L
'A' : (*c
)));
1540 for (c
= String
->Buffer
;
1544 *HashValue
= ((65599 * (*HashValue
)) + (ULONG
)(*c
));
1547 return STATUS_SUCCESS
;
1552 return STATUS_INVALID_PARAMETER
;
1559 * Same as RtlUnicodeStringToOemString but doesn't write terminating null
1560 * Does a partial copy if the dest buffer is too small
1564 RtlUnicodeStringToCountedOemString(
1565 IN OUT POEM_STRING OemDest
,
1566 IN PUNICODE_STRING UniSource
,
1567 IN BOOLEAN AllocateDestinationString
)
1570 ULONG Length
; //excluding nullterm
1572 if (NlsMbOemCodePageTag
== TRUE
)
1573 Length
= RtlUnicodeStringToAnsiSize(UniSource
) - sizeof(CHAR
);
1575 Length
= (UniSource
->Length
/ sizeof(WCHAR
));
1577 if (Length
> 0x0000FFFF)
1578 return STATUS_INVALID_PARAMETER_2
;
1580 OemDest
->Length
= (WORD
)(Length
);
1582 if (AllocateDestinationString
)
1584 OemDest
->Buffer
= RtlpAllocateStringMemory(Length
, TAG_OSTR
);
1585 if (OemDest
->Buffer
== NULL
)
1586 return STATUS_NO_MEMORY
;
1588 OemDest
->MaximumLength
= Length
;
1590 else if (OemDest
->MaximumLength
== 0)
1592 return STATUS_BUFFER_TOO_SMALL
;
1594 else if (Length
> OemDest
->MaximumLength
)
1596 OemDest
->Length
= OemDest
->MaximumLength
;
1599 Status
= RtlUnicodeToOemN (OemDest
->Buffer
,
1605 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
1607 RtlpFreeStringMemory(OemDest
->Buffer
, TAG_OSTR
);
1618 RtlLargeIntegerToChar(
1619 IN PLARGE_INTEGER Value
,
1622 IN OUT PCHAR String
)
1626 ULONGLONG v
= Value
->QuadPart
;
1635 if ((Radix
!= 2) && (Radix
!= 8) &&
1636 (Radix
!= 10) && (Radix
!= 16))
1637 return STATUS_INVALID_PARAMETER
;
1640 while (v
|| tp
== temp
)
1651 if ((ULONG
)((ULONG_PTR
)tp
- (ULONG_PTR
)temp
) >= Length
)
1652 return STATUS_BUFFER_TOO_SMALL
;
1659 return STATUS_SUCCESS
;
1666 * dest is never '\0' terminated because it may be equal to src, and src
1667 * might not be '\0' terminated. dest->Length is only set upon success.
1671 RtlUpcaseUnicodeString(
1672 IN OUT PUNICODE_STRING UniDest
,
1673 IN PCUNICODE_STRING UniSource
,
1674 IN BOOLEAN AllocateDestinationString
)
1679 if (AllocateDestinationString
== TRUE
)
1681 UniDest
->MaximumLength
= UniSource
->Length
;
1682 UniDest
->Buffer
= RtlpAllocateStringMemory(UniDest
->MaximumLength
, TAG_USTR
);
1683 if (UniDest
->Buffer
== NULL
)
1684 return STATUS_NO_MEMORY
;
1686 else if (UniSource
->Length
> UniDest
->MaximumLength
)
1688 return STATUS_BUFFER_TOO_SMALL
;
1691 UniDest
->Length
= UniSource
->Length
;
1693 Src
= UniSource
->Buffer
;
1694 Dest
= UniDest
->Buffer
;
1695 for (i
= 0; i
< UniSource
->Length
/ sizeof(WCHAR
); i
++)
1697 *Dest
= RtlUpcaseUnicodeChar (*Src
);
1702 return STATUS_SUCCESS
;
1709 * This function always writes a terminating '\0'.
1710 * It performs a partial copy if ansi is too small.
1714 RtlUpcaseUnicodeStringToAnsiString(
1715 IN OUT PANSI_STRING AnsiDest
,
1716 IN PUNICODE_STRING UniSource
,
1717 IN BOOLEAN AllocateDestinationString
)
1720 ULONG Length
; /* including nullterm */
1722 if (NlsMbCodePageTag
== TRUE
)
1723 Length
= RtlUnicodeStringToAnsiSize(UniSource
);
1725 Length
= (UniSource
->Length
/ sizeof(WCHAR
)) + sizeof(CHAR
);
1727 if (Length
> 0x0000FFFF)
1728 return STATUS_INVALID_PARAMETER_2
;
1730 AnsiDest
->Length
= (WORD
)(Length
- sizeof(CHAR
));
1732 if (AllocateDestinationString
)
1734 AnsiDest
->Buffer
= RtlpAllocateStringMemory(Length
, TAG_ASTR
);
1735 if (AnsiDest
->Buffer
== NULL
)
1736 return STATUS_NO_MEMORY
;
1738 AnsiDest
->MaximumLength
= Length
;
1740 else if (AnsiDest
->MaximumLength
== 0)
1742 return STATUS_BUFFER_TOO_SMALL
;
1744 else if (Length
> AnsiDest
->MaximumLength
)
1746 /* make room for nullterm */
1747 AnsiDest
->Length
= AnsiDest
->MaximumLength
- sizeof(CHAR
);
1750 /* FIXME: do we need this??????? -Gunnar */
1751 RtlZeroMemory (AnsiDest
->Buffer
,
1754 Status
= RtlUpcaseUnicodeToMultiByteN (AnsiDest
->Buffer
,
1760 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
1762 RtlpFreeStringMemory(AnsiDest
->Buffer
, TAG_ASTR
);
1766 AnsiDest
->Buffer
[AnsiDest
->Length
] = 0;
1774 * This function always writes a terminating '\0'.
1775 * It performs a partial copy if ansi is too small.
1779 RtlUpcaseUnicodeStringToCountedOemString(
1780 IN OUT POEM_STRING OemDest
,
1781 IN PUNICODE_STRING UniSource
,
1782 IN BOOLEAN AllocateDestinationString
)
1785 ULONG Length
; /* excluding nullterm */
1787 if (NlsMbCodePageTag
== TRUE
)
1788 Length
= RtlUnicodeStringToAnsiSize(UniSource
) - sizeof(CHAR
);
1790 Length
= UniSource
->Length
/ sizeof(WCHAR
);
1792 if (Length
> 0x0000FFFF)
1793 return(STATUS_INVALID_PARAMETER_2
);
1795 OemDest
->Length
= (WORD
)(Length
);
1797 if (AllocateDestinationString
)
1799 OemDest
->Buffer
= RtlpAllocateStringMemory(Length
, TAG_OSTR
);
1800 if (OemDest
->Buffer
== NULL
)
1801 return(STATUS_NO_MEMORY
);
1803 /* FIXME: Do we need this????? */
1804 RtlZeroMemory (OemDest
->Buffer
, Length
);
1806 OemDest
->MaximumLength
= (WORD
)Length
;
1808 else if (OemDest
->MaximumLength
== 0)
1810 return(STATUS_BUFFER_TOO_SMALL
);
1812 else if (Length
> OemDest
->MaximumLength
)
1814 OemDest
->Length
= OemDest
->MaximumLength
;
1817 Status
= RtlUpcaseUnicodeToOemN(OemDest
->Buffer
,
1823 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
1825 RtlpFreeStringMemory(OemDest
->Buffer
, TAG_OSTR
);
1835 * Oem string is allways nullterminated
1836 * It performs a partial copy if oem is too small.
1840 RtlUpcaseUnicodeStringToOemString (
1841 IN OUT POEM_STRING OemDest
,
1842 IN PUNICODE_STRING UniSource
,
1843 IN BOOLEAN AllocateDestinationString
1847 ULONG Length
; /* including nullterm */
1849 if (NlsMbOemCodePageTag
== TRUE
)
1850 Length
= RtlUnicodeStringToAnsiSize(UniSource
);
1852 Length
= (UniSource
->Length
/ sizeof(WCHAR
)) + sizeof(CHAR
);
1854 if (Length
> 0x0000FFFF)
1855 return STATUS_INVALID_PARAMETER_2
;
1857 OemDest
->Length
= (WORD
)(Length
- sizeof(CHAR
));
1859 if (AllocateDestinationString
)
1861 OemDest
->Buffer
= RtlpAllocateStringMemory(Length
, TAG_OSTR
);
1862 if (OemDest
->Buffer
== NULL
)
1863 return STATUS_NO_MEMORY
;
1865 /* FIXME: Do we need this???? */
1866 RtlZeroMemory (OemDest
->Buffer
, Length
);
1868 OemDest
->MaximumLength
= (WORD
)Length
;
1870 else if (OemDest
->MaximumLength
== 0)
1872 return STATUS_BUFFER_OVERFLOW
;
1874 else if (Length
> OemDest
->MaximumLength
)
1876 /* make room for nullterm */
1877 OemDest
->Length
= OemDest
->MaximumLength
- sizeof(CHAR
);
1880 Status
= RtlUpcaseUnicodeToOemN (OemDest
->Buffer
,
1886 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
1888 RtlpFreeStringMemory(OemDest
->Buffer
, TAG_OSTR
);
1892 OemDest
->Buffer
[OemDest
->Length
] = 0;
1900 * Bytes calculated including nullterm
1904 RtlOemStringToUnicodeSize(IN POEM_STRING OemString
)
1908 //this function returns size including nullterm
1909 RtlMultiByteToUnicodeSize(&Size
,
1923 RtlStringFromGUID (IN REFGUID Guid
,
1924 OUT PUNICODE_STRING GuidString
)
1926 STATIC CONST PWCHAR Hex
= L
"0123456789ABCDEF";
1933 return STATUS_INVALID_PARAMETER
;
1937 L
"{%08lX-%04X-%04X-%02X%02X-",
1943 BufferPtr
= Buffer
+ 25;
1946 for (i
= 2; i
< 8; i
++)
1948 *BufferPtr
++ = Hex
[Guid
->Data4
[i
] >> 4];
1949 *BufferPtr
++ = Hex
[Guid
->Data4
[i
] & 0xf];
1952 *BufferPtr
++ = L
'}';
1953 *BufferPtr
++ = L
'\0';
1955 return RtlCreateUnicodeString (GuidString
, Buffer
);
1963 * Bytes calculated including nullterm
1967 RtlUnicodeStringToAnsiSize(
1968 IN PUNICODE_STRING UnicodeString
)
1972 //this function return size without nullterm!
1973 RtlUnicodeToMultiByteSize (&Size
,
1974 UnicodeString
->Buffer
,
1975 UnicodeString
->Length
);
1977 return Size
+ sizeof(CHAR
); //NB: incl. nullterm
1988 RtlCompareUnicodeString(
1989 IN PUNICODE_STRING String1
,
1990 IN PUNICODE_STRING String2
,
1991 IN BOOLEAN CaseInsensitive
)
1997 if (String1
&& String2
)
1999 len1
= String1
->Length
/ sizeof(WCHAR
);
2000 len2
= String2
->Length
/ sizeof(WCHAR
);
2001 s1
= String1
->Buffer
;
2002 s2
= String2
->Buffer
;
2006 if (CaseInsensitive
)
2010 c1
= len1
-- ? RtlUpcaseUnicodeChar (*s1
++) : 0;
2011 c2
= len2
-- ? RtlUpcaseUnicodeChar (*s2
++) : 0;
2012 if (!c1
|| !c2
|| c1
!= c2
)
2020 c1
= len1
-- ? *s1
++ : 0;
2021 c2
= len2
-- ? *s2
++ : 0;
2022 if (!c1
|| !c2
|| c1
!= c2
)
2039 IN OUT PSTRING DestinationString
,
2040 IN PSTRING SourceString
)
2044 if(SourceString
== NULL
)
2046 DestinationString
->Length
= 0;
2050 copylen
= min (DestinationString
->MaximumLength
,
2051 SourceString
->Length
);
2053 memcpy(DestinationString
->Buffer
, SourceString
->Buffer
, copylen
);
2054 if (DestinationString
->MaximumLength
>= copylen
+ sizeof(CHAR
))
2056 DestinationString
->Buffer
[copylen
] = 0;
2058 DestinationString
->Length
= copylen
;
2068 RtlCopyUnicodeString(
2069 IN OUT PUNICODE_STRING DestinationString
,
2070 IN PUNICODE_STRING SourceString
)
2074 if (SourceString
== NULL
)
2076 DestinationString
->Length
= 0;
2080 copylen
= min (DestinationString
->MaximumLength
,
2081 SourceString
->Length
);
2082 memcpy(DestinationString
->Buffer
, SourceString
->Buffer
, copylen
);
2083 if (DestinationString
->MaximumLength
>= copylen
+ sizeof(WCHAR
))
2085 DestinationString
->Buffer
[copylen
/ sizeof(WCHAR
)] = 0;
2087 DestinationString
->Length
= copylen
;
2094 * Creates a nullterminated UNICODE_STRING
2098 RtlCreateUnicodeString(
2099 IN OUT PUNICODE_STRING UniDest
,
2104 Length
= (wcslen (Source
) + 1) * sizeof(WCHAR
);
2105 UniDest
->Buffer
= RtlpAllocateStringMemory(Length
, TAG_USTR
);
2106 if (UniDest
->Buffer
== NULL
)
2109 RtlCopyMemory (UniDest
->Buffer
,
2113 UniDest
->MaximumLength
= Length
;
2114 UniDest
->Length
= Length
- sizeof (WCHAR
);
2124 RtlCreateUnicodeStringFromAsciiz(
2125 OUT PUNICODE_STRING Destination
,
2128 ANSI_STRING AnsiString
;
2131 RtlInitAnsiString (&AnsiString
,
2134 Status
= RtlAnsiStringToUnicodeString (Destination
,
2138 return NT_SUCCESS(Status
);
2145 * Dest is never '\0' terminated because it may be equal to src, and src
2146 * might not be '\0' terminated.
2147 * Dest->Length is only set upon success.
2150 RtlDowncaseUnicodeString(
2151 IN OUT PUNICODE_STRING UniDest
,
2152 IN PUNICODE_STRING UniSource
,
2153 IN BOOLEAN AllocateDestinationString
)
2158 if (AllocateDestinationString
)
2160 UniDest
->Buffer
= RtlpAllocateStringMemory(UniSource
->Length
, TAG_USTR
);
2161 if (UniDest
->Buffer
== NULL
)
2162 return STATUS_NO_MEMORY
;
2164 UniDest
->MaximumLength
= UniSource
->Length
;
2166 else if (UniSource
->Length
> UniDest
->MaximumLength
)
2168 return STATUS_BUFFER_TOO_SMALL
;
2171 UniDest
->Length
= UniSource
->Length
;
2173 Src
= UniSource
->Buffer
;
2174 Dest
= UniDest
->Buffer
;
2175 for (i
=0; i
< UniSource
->Length
/ sizeof(WCHAR
); i
++)
2181 else if (*Src
<= L
'Z')
2183 *Dest
= (*Src
+ (L
'a' - L
'A'));
2187 *Dest
= RtlDowncaseUnicodeChar(*Src
);
2194 return STATUS_SUCCESS
;
2201 * if src is NULL dest is unchanged.
2202 * dest is '\0' terminated when the MaximumLength allowes it.
2203 * When dest fits exactly in MaximumLength characters the '\0' is ommitted.
2206 RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination
,
2211 slen
= wcslen(Source
) * sizeof(WCHAR
);
2213 if (Destination
->Length
+ slen
> Destination
->MaximumLength
)
2214 return(STATUS_BUFFER_TOO_SMALL
);
2216 memcpy((char*)Destination
->Buffer
+ Destination
->Length
, Source
, slen
);
2217 Destination
->Length
+= slen
;
2218 /* append terminating '\0' if enough space */
2219 if( Destination
->MaximumLength
> Destination
->Length
)
2220 Destination
->Buffer
[Destination
->Length
/ sizeof(WCHAR
)] = 0;
2222 return(STATUS_SUCCESS
);
2229 * This function always writes a terminating '\0'.
2230 * If the dest buffer is too small a partial copy is NOT performed!
2234 RtlAnsiStringToUnicodeString(
2235 IN OUT PUNICODE_STRING UniDest
,
2236 IN PANSI_STRING AnsiSource
,
2237 IN BOOLEAN AllocateDestinationString
)
2240 ULONG Length
; //including nullterm
2242 if (NlsMbCodePageTag
== TRUE
)
2243 Length
= RtlAnsiStringToUnicodeSize(AnsiSource
);
2245 Length
= (AnsiSource
->Length
* sizeof(WCHAR
)) + sizeof(WCHAR
);
2247 if (Length
> 0xffff)
2248 return STATUS_INVALID_PARAMETER_2
;
2250 if (AllocateDestinationString
== TRUE
)
2252 UniDest
->Buffer
= RtlpAllocateStringMemory(Length
, TAG_USTR
);
2253 if (UniDest
->Buffer
== NULL
)
2254 return STATUS_NO_MEMORY
;
2256 UniDest
->MaximumLength
= Length
;
2258 else if (Length
> UniDest
->MaximumLength
)
2260 DPRINT("STATUS_BUFFER_TOO_SMALL\n");
2261 return STATUS_BUFFER_TOO_SMALL
;
2264 UniDest
->Length
= Length
- sizeof(WCHAR
);
2266 //FIXME: We don't need this??? -Gunnar
2267 RtlZeroMemory (UniDest
->Buffer
,
2270 Status
= RtlMultiByteToUnicodeN (UniDest
->Buffer
,
2274 AnsiSource
->Length
);
2276 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
2278 RtlpFreeStringMemory(UniDest
->Buffer
, TAG_USTR
);
2282 UniDest
->Buffer
[UniDest
->Length
/ sizeof(WCHAR
)] = 0;
2290 * if src is NULL dest is unchanged.
2291 * dest is never '\0' terminated.
2295 RtlAppendAsciizToString(
2296 IN OUT PSTRING Destination
,
2303 return STATUS_SUCCESS
;
2305 Length
= strlen (Source
);
2306 if (Destination
->Length
+ Length
>= Destination
->MaximumLength
)
2307 return STATUS_BUFFER_TOO_SMALL
;
2309 Ptr
= Destination
->Buffer
+ Destination
->Length
;
2316 Destination
->Length
+= Length
;
2318 return STATUS_SUCCESS
;
2326 RtlUpperString(PSTRING DestinationString
,
2327 PSTRING SourceString
)
2334 Length
= min(SourceString
->Length
,
2335 DestinationString
->MaximumLength
- 1);
2337 Src
= SourceString
->Buffer
;
2338 Dest
= DestinationString
->Buffer
;
2339 for (i
= 0; i
< Length
; i
++)
2341 *Dest
= RtlUpperChar(*Src
);
2347 DestinationString
->Length
= SourceString
->Length
;
2355 RtlxAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString
)
2357 return RtlAnsiStringToUnicodeSize(AnsiString
);
2365 RtlxOemStringToUnicodeSize(IN POEM_STRING OemString
)
2367 return RtlOemStringToUnicodeSize(OemString
);
2376 RtlxUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString
)
2378 return RtlUnicodeStringToAnsiSize(UnicodeString
);
2386 RtlxUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString
)
2388 return RtlUnicodeStringToOemSize(UnicodeString
);
2395 * See RtlpDuplicateUnicodeString
2398 RtlDuplicateUnicodeString(
2400 IN PUNICODE_STRING SourceString
,
2401 PUNICODE_STRING DestinationString
)
2403 if (SourceString
== NULL
|| DestinationString
== NULL
)
2404 return STATUS_INVALID_PARAMETER
;
2407 if (SourceString
->Length
== 0 && AddNull
!= 3)
2409 DestinationString
->Length
= 0;
2410 DestinationString
->MaximumLength
= 0;
2411 DestinationString
->Buffer
= NULL
;
2415 UINT DestMaxLength
= SourceString
->Length
;
2418 DestMaxLength
+= sizeof(UNICODE_NULL
);
2420 DestinationString
->Buffer
= RtlpAllocateStringMemory(DestMaxLength
, TAG_USTR
);
2421 if (DestinationString
->Buffer
== NULL
)
2422 return STATUS_NO_MEMORY
;
2424 RtlCopyMemory(DestinationString
->Buffer
, SourceString
->Buffer
, SourceString
->Length
);
2425 DestinationString
->Length
= SourceString
->Length
;
2426 DestinationString
->MaximumLength
= DestMaxLength
;
2429 DestinationString
->Buffer
[DestinationString
->Length
/ sizeof(WCHAR
)] = 0;
2432 return STATUS_SUCCESS
;
2439 RtlValidateUnicodeString(IN ULONG Flags
,
2440 IN PUNICODE_STRING UnicodeString
)
2442 /* currently no flags are supported! */
2446 ((UnicodeString
== NULL
) ||
2447 ((UnicodeString
->Length
!= 0) &&
2448 (UnicodeString
->Buffer
!= NULL
) &&
2449 ((UnicodeString
->Length
% sizeof(WCHAR
)) == 0) &&
2450 ((UnicodeString
->MaximumLength
% sizeof(WCHAR
)) == 0) &&
2451 (UnicodeString
->MaximumLength
>= UnicodeString
->Length
))))
2453 /* a NULL pointer as a unicode string is considered to be a valid unicode
2455 return STATUS_SUCCESS
;
2459 return STATUS_INVALID_PARAMETER
;