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
25 #include <ddk/ntddk.h>
27 #include <ntdll/rtl.h>
29 #include <ntos/minmax.h>
30 #define __NO_CTYPE_INLINES
36 /* GLOBALS *******************************************************************/
38 #define TAG_USTR TAG('U', 'S', 'T', 'R')
39 #define TAG_ASTR TAG('A', 'S', 'T', 'R')
40 #define TAG_OSTR TAG('O', 'S', 'T', 'R')
43 extern BOOLEAN NlsMbCodePageTag
;
44 extern BOOLEAN NlsMbOemCodePageTag
;
46 /* FUNCTIONS *****************************************************************/
53 RtlAnsiCharToUnicodeChar (IN CHAR AnsiChar
)
61 Size
= (NlsLeadByteInfo
[AnsiChar
] == 0) ? 1 : 2;
64 RtlMultiByteToUnicodeN (&UnicodeChar
,
78 * The calculated size in bytes including nullterm.
82 RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString
)
86 RtlMultiByteToUnicodeSize(&Size
,
99 * If src->length is zero dest is unchanged.
100 * Dest is never nullterminated.
104 RtlAppendStringToString(IN OUT PSTRING Destination
,
109 if (Source
->Length
== 0)
110 return(STATUS_SUCCESS
);
112 if (Destination
->Length
+ Source
->Length
>= Destination
->MaximumLength
)
113 return(STATUS_BUFFER_TOO_SMALL
);
115 Ptr
= Destination
->Buffer
+ Destination
->Length
;
119 Ptr
+= Source
->Length
;
122 Destination
->Length
+= Source
->Length
;
124 return(STATUS_SUCCESS
);
133 * If src->length is zero dest is unchanged.
134 * Dest is nullterminated when the MaximumLength allowes it.
135 * When dest fits exactly in MaximumLength characters the nullterm is ommitted.
139 RtlAppendUnicodeStringToString(
140 IN OUT PUNICODE_STRING Destination
,
141 IN PUNICODE_STRING Source
)
144 if ((Source
->Length
+ Destination
->Length
) > Destination
->MaximumLength
)
145 return STATUS_BUFFER_TOO_SMALL
;
147 memcpy((char*)Destination
->Buffer
+ Destination
->Length
, Source
->Buffer
, Source
->Length
);
148 Destination
->Length
+= Source
->Length
;
149 /* append terminating '\0' if enough space */
150 if( Destination
->MaximumLength
> Destination
->Length
)
151 Destination
->Buffer
[Destination
->Length
/ sizeof(WCHAR
)] = 0;
153 return STATUS_SUCCESS
;
178 if ((*String
== 'x') && isxdigit (String
[1]))
186 if (!isxdigit (*String
))
187 return STATUS_INVALID_PARAMETER
;
189 while (isxdigit (*String
) &&
190 (Val
= isdigit (*String
) ? * String
- '0' : (islower (*String
)
191 ? toupper (*String
) : *String
) - 'A' + 10) < Base
)
193 *Value
= *Value
* Base
+ Val
;
197 return STATUS_SUCCESS
;
210 IN BOOLEAN CaseInsensitive
)
216 if (String1
&& String2
)
218 len1
= String1
->Length
;
219 len2
= String2
->Length
;
220 s1
= String1
->Buffer
;
221 s2
= String2
->Buffer
;
229 c1
= len1
-- ? RtlUpperChar (*s1
++) : 0;
230 c2
= len2
-- ? RtlUpperChar (*s2
++) : 0;
231 if (!c1
|| !c2
|| c1
!= c2
)
239 c1
= len1
-- ? *s1
++ : 0;
240 c2
= len2
-- ? *s2
++ : 0;
241 if (!c1
|| !c2
|| c1
!= c2
)
256 * TRUE if strings are equal.
263 IN BOOLEAN CaseInsensitive
)
269 if (String1
->Length
!= String2
->Length
)
272 p1
= String1
->Buffer
;
273 p2
= String2
->Buffer
;
274 for (i
= 0; i
< String1
->Length
; i
++)
276 if (CaseInsensitive
== TRUE
)
278 c1
= RtlUpperChar (*p1
);
279 c2
= RtlUpperChar (*p2
);
302 * TRUE if strings are equal.
306 RtlEqualUnicodeString(
307 IN PUNICODE_STRING String1
,
308 IN PUNICODE_STRING String2
,
309 IN BOOLEAN CaseInsensitive
)
315 if (String1
->Length
!= String2
->Length
)
318 pw1
= String1
->Buffer
;
319 pw2
= String2
->Buffer
;
321 for (i
= 0; i
< String1
->Length
/ sizeof(WCHAR
); i
++)
323 if (CaseInsensitive
== TRUE
)
325 wc1
= RtlUpcaseUnicodeChar (*pw1
);
326 wc2
= RtlUpcaseUnicodeChar (*pw2
);
350 RtlFreeAnsiString(IN PANSI_STRING AnsiString
)
352 if (AnsiString
->Buffer
== NULL
)
355 ExFreePoolWithTag(AnsiString
->Buffer
, TAG_ASTR
);
357 AnsiString
->Buffer
= NULL
;
358 AnsiString
->Length
= 0;
359 AnsiString
->MaximumLength
= 0;
368 RtlFreeOemString(IN POEM_STRING OemString
)
370 if (OemString
->Buffer
== NULL
)
373 ExFreePoolWithTag(OemString
->Buffer
, TAG_OSTR
);
375 OemString
->Buffer
= NULL
;
376 OemString
->Length
= 0;
377 OemString
->MaximumLength
= 0;
386 RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString
)
388 if (UnicodeString
->Buffer
== NULL
)
391 ExFreePoolWithTag(UnicodeString
->Buffer
, TAG_USTR
);
393 UnicodeString
->Buffer
= NULL
;
394 UnicodeString
->Length
= 0;
395 UnicodeString
->MaximumLength
= 0;
403 RtlIsValidOemCharacter (
415 * If source is NULL the length of source is assumed to be 0.
419 RtlInitAnsiString(IN OUT PANSI_STRING DestinationString
,
420 IN PCSZ SourceString
)
424 if (SourceString
== NULL
)
426 DestinationString
->Length
= 0;
427 DestinationString
->MaximumLength
= 0;
431 DestSize
= strlen ((const char *)SourceString
);
432 DestinationString
->Length
= DestSize
;
433 DestinationString
->MaximumLength
= DestSize
+ sizeof(CHAR
);
435 DestinationString
->Buffer
= (PCHAR
)SourceString
;
444 * If source is NULL the length of source is assumed to be 0.
449 IN OUT PSTRING DestinationString
,
450 IN PCSZ SourceString
)
454 if (SourceString
== NULL
)
456 DestinationString
->Length
= 0;
457 DestinationString
->MaximumLength
= 0;
461 DestSize
= strlen((const char *)SourceString
);
462 DestinationString
->Length
= DestSize
;
463 DestinationString
->MaximumLength
= DestSize
+ sizeof(CHAR
);
465 DestinationString
->Buffer
= (PCHAR
)SourceString
;
473 * If source is NULL the length of source is assumed to be 0.
477 RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString
,
478 IN PCWSTR SourceString
)
482 DPRINT("RtlInitUnicodeString(DestinationString %x, SourceString %x)\n",
486 if (SourceString
== NULL
)
488 DestinationString
->Length
= 0;
489 DestinationString
->MaximumLength
= 0;
493 DestSize
= wcslen((PWSTR
)SourceString
) * sizeof(WCHAR
);
494 DestinationString
->Length
= DestSize
;
495 DestinationString
->MaximumLength
= DestSize
+ sizeof(WCHAR
);
497 DestinationString
->Buffer
= (PWSTR
)SourceString
;
504 RtlInitUnicodeStringEx(OUT PUNICODE_STRING DestinationString
,
505 IN PCWSTR SourceString
)
509 if (SourceString
!= NULL
)
511 Length
= wcslen(SourceString
) * sizeof(WCHAR
);
513 return STATUS_NAME_TOO_LONG
;
515 DestinationString
->Length
= Length
;
516 DestinationString
->MaximumLength
= Length
+ sizeof(WCHAR
);
517 DestinationString
->Buffer
= (PWSTR
)SourceString
;
521 DestinationString
->Length
= 0;
522 DestinationString
->MaximumLength
= 0;
523 DestinationString
->Buffer
= NULL
;
526 return STATUS_SUCCESS
;
533 * Writes at most length characters to the string str.
534 * Str is nullterminated when length allowes it.
535 * When str fits exactly in length characters the nullterm is ommitted.
556 if ((Radix
!= 2) && (Radix
!= 8) &&
557 (Radix
!= 10) && (Radix
!= 16))
559 return STATUS_INVALID_PARAMETER
;
563 while (v
|| tp
== temp
)
574 if (tp
- temp
>= Length
)
576 return STATUS_BUFFER_TOO_SMALL
;
584 return STATUS_SUCCESS
;
595 IN ULONG Base OPTIONAL
,
596 IN ULONG Length OPTIONAL
,
611 if ((Radix
!= 2) && (Radix
!= 8) &&
612 (Radix
!= 10) && (Radix
!= 16))
614 return STATUS_INVALID_PARAMETER
;
618 while (v
|| tp
== temp
)
629 if (tp
- temp
>= Length
)
631 return STATUS_BUFFER_TOO_SMALL
;
639 return STATUS_SUCCESS
;
649 RtlIntegerToUnicodeString(
651 IN ULONG Base
, /* optional */
652 IN OUT PUNICODE_STRING String
)
654 ANSI_STRING AnsiString
;
658 Status
= RtlIntegerToChar (Value
,
662 if (!NT_SUCCESS(Status
))
665 AnsiString
.Buffer
= Buffer
;
666 AnsiString
.Length
= strlen (Buffer
);
667 AnsiString
.MaximumLength
= sizeof(Buffer
);
669 Status
= RtlAnsiStringToUnicodeString (String
,
682 RtlInt64ToUnicodeString (
684 IN ULONG Base OPTIONAL
,
685 IN OUT PUNICODE_STRING String
688 LARGE_INTEGER LargeInt
;
689 ANSI_STRING AnsiString
;
693 LargeInt
.QuadPart
= Value
;
695 Status
= RtlLargeIntegerToChar (&LargeInt
,
699 if (!NT_SUCCESS(Status
))
702 AnsiString
.Buffer
= Buffer
;
703 AnsiString
.Length
= strlen (Buffer
);
704 AnsiString
.MaximumLength
= sizeof(Buffer
);
706 Status
= RtlAnsiStringToUnicodeString (String
,
718 * TRUE if String2 contains String1 as a prefix.
723 PANSI_STRING String1
,
724 PANSI_STRING String2
,
725 BOOLEAN CaseInsensitive
)
731 if (String2
->Length
< String1
->Length
)
734 Length
= String1
->Length
;
735 pc1
= String1
->Buffer
;
736 pc2
= String2
->Buffer
;
744 if (RtlUpperChar (*pc1
++) != RtlUpperChar (*pc2
++))
752 if (*pc1
++ != *pc2
++)
766 * TRUE if String2 contains String1 as a prefix.
770 RtlPrefixUnicodeString(
771 PUNICODE_STRING String1
,
772 PUNICODE_STRING String2
,
773 BOOLEAN CaseInsensitive
)
779 if (String2
->Length
< String1
->Length
)
782 Length
= String1
->Length
/ 2;
783 pc1
= String1
->Buffer
;
784 pc2
= String2
->Buffer
;
792 if (RtlUpcaseUnicodeChar (*pc1
++)
793 != RtlUpcaseUnicodeChar (*pc2
++))
801 if( *pc1
++ != *pc2
++ )
815 * Note that regardless of success or failure status, we should leave the
816 * partial value in Value. An error is never returned based on the chars
819 * This function does check the base. Only 2, 8, 10, 16 are permitted,
820 * else STATUS_INVALID_PARAMETER is returned.
824 RtlUnicodeStringToInteger(
825 IN PUNICODE_STRING String
,
833 BOOLEAN addneg
= FALSE
;
834 NTSTATUS Status
= STATUS_SUCCESS
;
837 Str
= String
->Buffer
;
839 if( Base
&& Base
!= 2 && Base
!= 8 && Base
!= 10 && Base
!= 16 )
840 return STATUS_INVALID_PARAMETER
;
842 for (i
= 0; i
< String
->Length
/ sizeof(WCHAR
); i
++)
849 else if (*Str
== L
'o')
854 else if (*Str
== L
'd')
859 else if (*Str
== L
'x')
864 else if (*Str
== L
'+')
868 else if (*Str
== L
'-')
873 else if ((*Str
> L
'1') && (Base
== 2))
877 else if (((*Str
> L
'7') || (*Str
< L
'0')) && (Base
== 8))
881 else if (((*Str
> L
'9') || (*Str
< L
'0')) && (Base
== 10))
885 else if ( ((*Str
> L
'9') || (*Str
< L
'0')) &&
886 ((towupper (*Str
) > L
'F') || (towupper (*Str
) < L
'A')) &&
894 Str
= String
->Buffer
+ lenmin
;
899 while (iswxdigit (*Str
) &&
903 (towupper (*Str
) - L
'A' + 10)) < Base
)
905 *Value
= *Value
* Base
+ Val
;
921 * Bytes necessary for the conversion including nullterm.
925 RtlUnicodeStringToOemSize(
926 IN PUNICODE_STRING UnicodeString
)
930 RtlUnicodeToMultiByteSize (&Size
,
931 UnicodeString
->Buffer
,
932 UnicodeString
->Length
);
934 return Size
+1; //NB: incl. nullterm
943 * See RtlpUnicodeStringToAnsiString
947 RtlUnicodeStringToAnsiString(
948 IN OUT PANSI_STRING AnsiDest
,
949 IN PUNICODE_STRING UniSource
,
950 IN BOOLEAN AllocateDestinationString
)
952 return RtlpUnicodeStringToAnsiString(
955 AllocateDestinationString
,
964 * This function always writes a terminating '\0'.
965 * It performs a partial copy if ansi is too small.
969 RtlpUnicodeStringToAnsiString(
970 IN OUT PANSI_STRING AnsiDest
,
971 IN PUNICODE_STRING UniSource
,
972 IN BOOLEAN AllocateDestinationString
,
973 IN POOL_TYPE PoolType
)
975 NTSTATUS Status
= STATUS_SUCCESS
;
976 ULONG Length
; //including nullterm
978 if (NlsMbCodePageTag
== TRUE
)
980 Length
= RtlUnicodeStringToAnsiSize(UniSource
);
983 Length
= (UniSource
->Length
/ sizeof(WCHAR
)) + sizeof(CHAR
);
985 AnsiDest
->Length
= Length
- sizeof(CHAR
);
987 if (AllocateDestinationString
)
989 AnsiDest
->Buffer
= ExAllocatePoolWithTag(PoolType
, Length
, TAG_ASTR
);
990 if (AnsiDest
->Buffer
== NULL
)
991 return STATUS_NO_MEMORY
;
993 AnsiDest
->MaximumLength
= Length
;
995 else if (AnsiDest
->MaximumLength
== 0)
997 return STATUS_BUFFER_TOO_SMALL
;
999 else if (Length
> AnsiDest
->MaximumLength
)
1001 //make room for nullterm
1002 AnsiDest
->Length
= AnsiDest
->MaximumLength
- sizeof(CHAR
);
1005 Status
= RtlUnicodeToMultiByteN (AnsiDest
->Buffer
,
1011 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
1013 ExFreePoolWithTag(AnsiDest
->Buffer
, TAG_ASTR
);
1017 AnsiDest
->Buffer
[AnsiDest
->Length
] = 0;
1026 * See RtlpOemStringToUnicodeString
1030 RtlOemStringToUnicodeString(
1031 IN OUT PUNICODE_STRING UniDest
,
1032 IN POEM_STRING OemSource
,
1033 IN BOOLEAN AllocateDestinationString
)
1035 return RtlpOemStringToUnicodeString(
1038 AllocateDestinationString
,
1047 * This function always writes a terminating '\0'.
1048 * Does NOT perform a partial copy if unicode is too small!
1052 RtlpOemStringToUnicodeString(
1053 IN OUT PUNICODE_STRING UniDest
,
1054 IN POEM_STRING OemSource
,
1055 IN BOOLEAN AllocateDestinationString
,
1056 IN POOL_TYPE PoolType
)
1059 ULONG Length
; //including nullterm
1061 if (NlsMbOemCodePageTag
== TRUE
)
1062 Length
= RtlOemStringToUnicodeSize(OemSource
);
1064 Length
= (OemSource
->Length
* sizeof(WCHAR
)) + sizeof(WCHAR
);
1066 if (Length
> 0xffff)
1067 return STATUS_INVALID_PARAMETER_2
;
1069 UniDest
->Length
= (WORD
)(Length
- sizeof(WCHAR
));
1071 if (AllocateDestinationString
)
1073 UniDest
->Buffer
= ExAllocatePoolWithTag(PoolType
, Length
, TAG_USTR
);
1074 if (UniDest
->Buffer
== NULL
)
1075 return STATUS_NO_MEMORY
;
1077 UniDest
->MaximumLength
= Length
;
1079 else if (Length
> UniDest
->MaximumLength
)
1081 DPRINT("STATUS_BUFFER_TOO_SMALL\n");
1082 return STATUS_BUFFER_TOO_SMALL
;
1085 //FIXME: Do we need this????? -Gunnar
1086 RtlZeroMemory (UniDest
->Buffer
,
1089 Status
= RtlOemToUnicodeN (UniDest
->Buffer
,
1095 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
1097 ExFreePoolWithTag(UniDest
->Buffer
, TAG_USTR
);
1101 UniDest
->Buffer
[UniDest
->Length
/ sizeof(WCHAR
)] = 0;
1102 return STATUS_SUCCESS
;
1110 * See RtlpUnicodeStringToOemString.
1114 RtlUnicodeStringToOemString(
1115 IN OUT POEM_STRING OemDest
,
1116 IN PUNICODE_STRING UniSource
,
1117 IN BOOLEAN AllocateDestinationString
)
1119 return RtlpUnicodeStringToOemString(
1122 AllocateDestinationString
,
1132 * This function always '\0' terminates the string returned.
1136 RtlpUnicodeStringToOemString(
1137 IN OUT POEM_STRING OemDest
,
1138 IN PUNICODE_STRING UniSource
,
1139 IN BOOLEAN AllocateDestinationString
,
1140 IN POOL_TYPE PoolType
)
1142 NTSTATUS Status
= STATUS_SUCCESS
;
1143 ULONG Length
; //including nullterm
1145 if (NlsMbOemCodePageTag
== TRUE
)
1146 Length
= RtlUnicodeStringToAnsiSize (UniSource
);
1148 Length
= (UniSource
->Length
/ sizeof(WCHAR
)) + sizeof(CHAR
);
1150 if (Length
> 0x0000FFFF)
1151 return STATUS_INVALID_PARAMETER_2
;
1153 OemDest
->Length
= (WORD
)(Length
- sizeof(CHAR
));
1155 if (AllocateDestinationString
)
1157 OemDest
->Buffer
= ExAllocatePoolWithTag(PoolType
, Length
, TAG_OSTR
);
1158 if (OemDest
->Buffer
== NULL
)
1159 return STATUS_NO_MEMORY
;
1161 OemDest
->MaximumLength
= Length
;
1163 else if (OemDest
->MaximumLength
== 0)
1165 return STATUS_BUFFER_TOO_SMALL
;
1167 else if (Length
> OemDest
->MaximumLength
)
1169 //make room for nullterm
1170 OemDest
->Length
= OemDest
->MaximumLength
- sizeof(CHAR
);
1173 Status
= RtlUnicodeToOemN (OemDest
->Buffer
,
1179 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
1181 ExFreePoolWithTag(OemDest
->Buffer
, TAG_OSTR
);
1185 OemDest
->Buffer
[OemDest
->Length
] = 0;
1191 #define ITU_IMPLEMENTED_TESTS (IS_TEXT_UNICODE_ODD_LENGTH|IS_TEXT_UNICODE_SIGNATURE)
1198 * The length of the string if all tests were passed, 0 otherwise.
1201 RtlIsTextUnicode (PVOID Buffer
,
1206 ULONG in_flags
= (ULONG
)-1;
1207 ULONG out_flags
= 0;
1216 * Apply various tests to the text string. According to the
1217 * docs, each test "passed" sets the corresponding flag in
1218 * the output flags. But some of the tests are mutually
1219 * exclusive, so I don't see how you could pass all tests ...
1222 /* Check for an odd length ... pass if even. */
1224 out_flags
|= IS_TEXT_UNICODE_ODD_LENGTH
;
1226 /* Check for the BOM (byte order mark). */
1228 out_flags
|= IS_TEXT_UNICODE_SIGNATURE
;
1231 /* Check for the reverse BOM (byte order mark). */
1233 out_flags
|= IS_TEXT_UNICODE_REVERSE_SIGNATURE
;
1236 /* FIXME: Add more tests */
1239 * Check whether the string passed all of the tests.
1241 in_flags
&= ITU_IMPLEMENTED_TESTS
;
1242 if ((out_flags
& in_flags
) != in_flags
)
1257 * See RtlpOemStringToCountedUnicodeString
1261 RtlOemStringToCountedUnicodeString(
1262 IN OUT PUNICODE_STRING UniDest
,
1263 IN POEM_STRING OemSource
,
1264 IN BOOLEAN AllocateDestinationString
)
1266 return RtlpOemStringToCountedUnicodeString(
1269 AllocateDestinationString
,
1278 * Same as RtlOemStringToUnicodeString but doesn't write terminating null
1279 * A partial copy is NOT performed if the dest buffer is too small!
1283 RtlpOemStringToCountedUnicodeString(
1284 IN OUT PUNICODE_STRING UniDest
,
1285 IN POEM_STRING OemSource
,
1286 IN BOOLEAN AllocateDestinationString
,
1287 IN POOL_TYPE PoolType
)
1290 ULONG Length
; //excluding nullterm
1292 if (NlsMbCodePageTag
== TRUE
)
1293 Length
= RtlOemStringToUnicodeSize(OemSource
) - sizeof(WCHAR
);
1295 Length
= OemSource
->Length
* sizeof(WCHAR
);
1298 return STATUS_INVALID_PARAMETER_2
;
1300 if (AllocateDestinationString
== TRUE
)
1302 UniDest
->Buffer
= ExAllocatePoolWithTag (PoolType
, Length
, TAG_USTR
);
1303 if (UniDest
->Buffer
== NULL
)
1304 return STATUS_NO_MEMORY
;
1306 UniDest
->MaximumLength
= Length
;
1308 else if (Length
> UniDest
->MaximumLength
)
1310 return STATUS_BUFFER_TOO_SMALL
;
1313 UniDest
->Length
= Length
;
1315 Status
= RtlOemToUnicodeN (UniDest
->Buffer
,
1321 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
1323 ExFreePoolWithTag(UniDest
->Buffer
, TAG_USTR
);
1335 * TRUE if the names are equal, FALSE if not
1338 * The comparison is case insensitive.
1342 RtlEqualComputerName(
1343 IN PUNICODE_STRING ComputerName1
,
1344 IN PUNICODE_STRING ComputerName2
)
1346 OEM_STRING OemString1
;
1347 OEM_STRING OemString2
;
1348 BOOLEAN Result
= FALSE
;
1350 if (NT_SUCCESS(RtlUpcaseUnicodeStringToOemString( &OemString1
, ComputerName1
, TRUE
)))
1352 if (NT_SUCCESS(RtlUpcaseUnicodeStringToOemString( &OemString2
, ComputerName2
, TRUE
)))
1354 Result
= RtlEqualString( &OemString1
, &OemString2
, TRUE
);
1355 RtlFreeOemString( &OemString2
);
1357 RtlFreeOemString( &OemString1
);
1367 * TRUE if the names are equal, FALSE if not
1370 * The comparison is case insensitive.
1374 RtlEqualDomainName (
1375 IN PUNICODE_STRING DomainName1
,
1376 IN PUNICODE_STRING DomainName2
1379 return RtlEqualComputerName(DomainName1
, DomainName2
);
1389 RtlEqualDomainName (
1390 IN PUNICODE_STRING DomainName1,
1391 IN PUNICODE_STRING DomainName2
1394 OEM_STRING OemString1;
1395 OEM_STRING OemString2;
1398 RtlUpcaseUnicodeStringToOemString (&OemString1,
1401 RtlUpcaseUnicodeStringToOemString (&OemString2,
1405 Result = RtlEqualString (&OemString1,
1409 RtlFreeOemString (&OemString1);
1410 RtlFreeOemString (&OemString2);
1420 * RIPPED FROM WINE's ntdll\rtlstr.c rev 1.45
1422 * Convert a string representation of a GUID into a GUID.
1425 * str [I] String representation in the format "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
1426 * guid [O] Destination for the converted GUID
1429 * Success: STATUS_SUCCESS. guid contains the converted value.
1430 * Failure: STATUS_INVALID_PARAMETER, if str is not in the expected format.
1433 * See RtlStringFromGUID.
1438 IN UNICODE_STRING
*str
,
1443 const WCHAR
*lpszCLSID
= str
->Buffer
;
1444 BYTE
* lpOut
= (BYTE
*)guid
;
1446 //TRACE("(%s,%p)\n", debugstr_us(str), guid);
1448 /* Convert string: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
1449 * to memory: DWORD... WORD WORD BYTES............
1456 if (*lpszCLSID
!= '{')
1457 return STATUS_INVALID_PARAMETER
;
1464 if (*lpszCLSID
!= '-')
1465 return STATUS_INVALID_PARAMETER
;
1469 if (*lpszCLSID
!= '}')
1470 return STATUS_INVALID_PARAMETER
;
1475 WCHAR ch
= *lpszCLSID
, ch2
= lpszCLSID
[1];
1478 /* Read two hex digits as a byte value */
1479 if (ch
>= '0' && ch
<= '9')
1481 else if (ch
>= 'a' && ch
<= 'f')
1483 else if (ch
>= 'A' && ch
<= 'F')
1486 return STATUS_INVALID_PARAMETER
;
1488 if (ch2
>= '0' && ch2
<= '9')
1490 else if (ch2
>= 'a' && ch2
<= 'f')
1491 ch2
= ch2
- 'a' + 10;
1492 else if (ch2
>= 'A' && ch2
<= 'F')
1493 ch2
= ch2
- 'A' + 10;
1495 return STATUS_INVALID_PARAMETER
;
1497 byte
= ch
<< 4 | ch2
;
1501 #ifndef WORDS_BIGENDIAN
1502 /* For Big Endian machines, we store the data such that the
1503 * dword/word members can be read as DWORDS and WORDS correctly. */
1535 lpszCLSID
++; /* Skip 2nd character of byte */
1543 return STATUS_SUCCESS
;
1551 RtlEraseUnicodeString(
1552 IN PUNICODE_STRING String
)
1554 if (String
->Buffer
== NULL
)
1557 if (String
->MaximumLength
== 0)
1560 memset (String
->Buffer
,
1562 String
->MaximumLength
);
1572 RtlHashUnicodeString(
1573 IN
const UNICODE_STRING
*String
,
1574 IN BOOLEAN CaseInSensitive
,
1575 IN ULONG HashAlgorithm
,
1576 OUT PULONG HashValue
1580 return STATUS_NOT_IMPLEMENTED
;
1587 * See RtlpUnicodeStringToCountedOemString.
1591 RtlUnicodeStringToCountedOemString(
1592 IN OUT POEM_STRING OemDest
,
1593 IN PUNICODE_STRING UniSource
,
1594 IN BOOLEAN AllocateDestinationString
)
1596 return RtlpUnicodeStringToCountedOemString(
1599 AllocateDestinationString
,
1607 * Same as RtlUnicodeStringToOemString but doesn't write terminating null
1608 * Does a partial copy if the dest buffer is too small
1612 RtlpUnicodeStringToCountedOemString(
1613 IN OUT POEM_STRING OemDest
,
1614 IN PUNICODE_STRING UniSource
,
1615 IN BOOLEAN AllocateDestinationString
,
1616 IN POOL_TYPE PoolType
)
1619 ULONG Length
; //excluding nullterm
1621 if (NlsMbOemCodePageTag
== TRUE
)
1622 Length
= RtlUnicodeStringToAnsiSize(UniSource
) - sizeof(CHAR
);
1624 Length
= (UniSource
->Length
/ sizeof(WCHAR
));
1626 if (Length
> 0x0000FFFF)
1627 return STATUS_INVALID_PARAMETER_2
;
1629 OemDest
->Length
= (WORD
)(Length
);
1631 if (AllocateDestinationString
)
1633 OemDest
->Buffer
= ExAllocatePoolWithTag(PoolType
, Length
, TAG_OSTR
);
1634 if (OemDest
->Buffer
== NULL
)
1635 return STATUS_NO_MEMORY
;
1637 OemDest
->MaximumLength
= Length
;
1639 else if (OemDest
->MaximumLength
== 0)
1641 return STATUS_BUFFER_TOO_SMALL
;
1643 else if (Length
> OemDest
->MaximumLength
)
1645 OemDest
->Length
= OemDest
->MaximumLength
;
1648 Status
= RtlUnicodeToOemN (OemDest
->Buffer
,
1654 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
1656 ExFreePoolWithTag(OemDest
->Buffer
, TAG_OSTR
);
1668 RtlLargeIntegerToChar(
1669 IN PLARGE_INTEGER Value
,
1672 IN OUT PCHAR String
)
1676 ULONGLONG v
= Value
->QuadPart
;
1685 if ((Radix
!= 2) && (Radix
!= 8) &&
1686 (Radix
!= 10) && (Radix
!= 16))
1687 return STATUS_INVALID_PARAMETER
;
1690 while (v
|| tp
== temp
)
1701 if (tp
- temp
>= Length
)
1702 return STATUS_BUFFER_TOO_SMALL
;
1709 return STATUS_SUCCESS
;
1718 * See RtlpUpcaseUnicodeString
1722 RtlUpcaseUnicodeString(
1723 IN OUT PUNICODE_STRING UniDest
,
1724 IN PCUNICODE_STRING UniSource
,
1725 IN BOOLEAN AllocateDestinationString
)
1728 return RtlpUpcaseUnicodeString(
1731 AllocateDestinationString
,
1740 * dest is never '\0' terminated because it may be equal to src, and src
1741 * might not be '\0' terminated. dest->Length is only set upon success.
1745 RtlpUpcaseUnicodeString(
1746 IN OUT PUNICODE_STRING UniDest
,
1747 IN PCUNICODE_STRING UniSource
,
1748 IN BOOLEAN AllocateDestinationString
,
1749 IN POOL_TYPE PoolType
)
1754 if (AllocateDestinationString
== TRUE
)
1756 UniDest
->MaximumLength
= UniSource
->Length
;
1757 UniDest
->Buffer
= ExAllocatePoolWithTag(PoolType
, UniDest
->MaximumLength
, TAG_USTR
);
1758 if (UniDest
->Buffer
== NULL
)
1759 return STATUS_NO_MEMORY
;
1761 else if (UniSource
->Length
> UniDest
->MaximumLength
)
1763 return STATUS_BUFFER_TOO_SMALL
;
1766 UniDest
->Length
= UniSource
->Length
;
1768 Src
= UniSource
->Buffer
;
1769 Dest
= UniDest
->Buffer
;
1770 for (i
= 0; i
< UniSource
->Length
/ sizeof(WCHAR
); i
++)
1772 *Dest
= RtlUpcaseUnicodeChar (*Src
);
1777 return STATUS_SUCCESS
;
1786 * See RtlpUpcaseUnicodeStringToAnsiString
1790 RtlUpcaseUnicodeStringToAnsiString(
1791 IN OUT PANSI_STRING AnsiDest
,
1792 IN PUNICODE_STRING UniSource
,
1793 IN BOOLEAN AllocateDestinationString
)
1795 return RtlpUpcaseUnicodeStringToAnsiString(
1798 AllocateDestinationString
,
1806 * This function always writes a terminating '\0'.
1807 * It performs a partial copy if ansi is too small.
1811 RtlpUpcaseUnicodeStringToAnsiString(
1812 IN OUT PANSI_STRING AnsiDest
,
1813 IN PUNICODE_STRING UniSource
,
1814 IN BOOLEAN AllocateDestinationString
,
1815 IN POOL_TYPE PoolType
)
1818 ULONG Length
; //including nullterm
1820 if (NlsMbCodePageTag
== TRUE
)
1821 Length
= RtlUnicodeStringToAnsiSize(UniSource
);
1823 Length
= (UniSource
->Length
/ sizeof(WCHAR
)) + sizeof(CHAR
);
1825 if (Length
> 0x0000FFFF)
1826 return STATUS_INVALID_PARAMETER_2
;
1828 AnsiDest
->Length
= (WORD
)(Length
- sizeof(CHAR
));
1830 if (AllocateDestinationString
)
1832 AnsiDest
->Buffer
= ExAllocatePoolWithTag(PoolType
, Length
, TAG_ASTR
);
1833 if (AnsiDest
->Buffer
== NULL
)
1834 return STATUS_NO_MEMORY
;
1836 AnsiDest
->MaximumLength
= Length
;
1838 else if (AnsiDest
->MaximumLength
== 0)
1840 return STATUS_BUFFER_TOO_SMALL
;
1842 else if (Length
> AnsiDest
->MaximumLength
)
1844 //make room for nullterm
1845 AnsiDest
->Length
= AnsiDest
->MaximumLength
- sizeof(CHAR
);
1848 //FIXME: do we need this??????? -Gunnar
1849 RtlZeroMemory (AnsiDest
->Buffer
,
1852 Status
= RtlUpcaseUnicodeToMultiByteN (AnsiDest
->Buffer
,
1858 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
1860 ExFreePoolWithTag(AnsiDest
->Buffer
, TAG_ASTR
);
1864 AnsiDest
->Buffer
[AnsiDest
->Length
] = 0;
1874 * See RtlpUpcaseUnicodeStringToCountedOemString
1878 RtlUpcaseUnicodeStringToCountedOemString(
1879 IN OUT POEM_STRING OemDest
,
1880 IN PUNICODE_STRING UniSource
,
1881 IN BOOLEAN AllocateDestinationString
)
1883 return RtlpUpcaseUnicodeStringToCountedOemString(
1886 AllocateDestinationString
,
1896 * Same as RtlUpcaseUnicodeStringToOemString but doesn't write terminating null
1897 * It performs a partial copy if oem is too small.
1901 RtlpUpcaseUnicodeStringToCountedOemString(
1902 IN OUT POEM_STRING OemDest
,
1903 IN PUNICODE_STRING UniSource
,
1904 IN BOOLEAN AllocateDestinationString
,
1905 IN POOL_TYPE PoolType
)
1908 ULONG Length
; //excluding nullterm
1910 if (NlsMbCodePageTag
== TRUE
)
1911 Length
= RtlUnicodeStringToAnsiSize(UniSource
) - sizeof(CHAR
);
1913 Length
= UniSource
->Length
/ sizeof(WCHAR
);
1915 if (Length
> 0x0000FFFF)
1916 return(STATUS_INVALID_PARAMETER_2
);
1918 OemDest
->Length
= (WORD
)(Length
);
1920 if (AllocateDestinationString
)
1922 OemDest
->Buffer
= ExAllocatePoolWithTag(PoolType
, Length
, TAG_OSTR
);
1923 if (OemDest
->Buffer
== NULL
)
1924 return(STATUS_NO_MEMORY
);
1926 //FIXME: Do we need this?????
1927 RtlZeroMemory (OemDest
->Buffer
, Length
);
1929 OemDest
->MaximumLength
= (WORD
)Length
;
1931 else if (OemDest
->MaximumLength
== 0)
1933 return(STATUS_BUFFER_TOO_SMALL
);
1935 else if (Length
> OemDest
->MaximumLength
)
1937 OemDest
->Length
= OemDest
->MaximumLength
;
1940 Status
= RtlUpcaseUnicodeToOemN(OemDest
->Buffer
,
1946 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
1948 ExFreePoolWithTag(OemDest
->Buffer
, TAG_OSTR
);
1959 * See RtlpUpcaseUnicodeStringToOemString
1963 RtlUpcaseUnicodeStringToOemString (
1964 IN OUT POEM_STRING OemDest
,
1965 IN PUNICODE_STRING UniSource
,
1966 IN BOOLEAN AllocateDestinationString
1969 return RtlpUpcaseUnicodeStringToOemString(
1972 AllocateDestinationString
,
1981 * Oem string is allways nullterminated
1982 * It performs a partial copy if oem is too small.
1986 RtlpUpcaseUnicodeStringToOemString (
1987 IN OUT POEM_STRING OemDest
,
1988 IN PUNICODE_STRING UniSource
,
1989 IN BOOLEAN AllocateDestinationString
,
1990 IN POOL_TYPE PoolType
1994 ULONG Length
; //including nullterm
1996 if (NlsMbOemCodePageTag
== TRUE
)
1997 Length
= RtlUnicodeStringToAnsiSize(UniSource
);
1999 Length
= (UniSource
->Length
/ sizeof(WCHAR
)) + sizeof(CHAR
);
2001 if (Length
> 0x0000FFFF)
2002 return STATUS_INVALID_PARAMETER_2
;
2004 OemDest
->Length
= (WORD
)(Length
- sizeof(CHAR
));
2006 if (AllocateDestinationString
)
2008 OemDest
->Buffer
= ExAllocatePoolWithTag(PoolType
, Length
, TAG_OSTR
);
2009 if (OemDest
->Buffer
== NULL
)
2010 return STATUS_NO_MEMORY
;
2012 //FIXME: Do we need this????
2013 RtlZeroMemory (OemDest
->Buffer
, Length
);
2015 OemDest
->MaximumLength
= (WORD
)Length
;
2017 else if (OemDest
->MaximumLength
== 0)
2019 return STATUS_BUFFER_OVERFLOW
;
2021 else if (Length
> OemDest
->MaximumLength
)
2023 //make room for nullterm
2024 OemDest
->Length
= OemDest
->MaximumLength
- sizeof(CHAR
);
2027 Status
= RtlUpcaseUnicodeToOemN (OemDest
->Buffer
,
2033 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
2035 ExFreePoolWithTag(OemDest
->Buffer
, TAG_OSTR
);
2039 OemDest
->Buffer
[OemDest
->Length
] = 0;
2048 * Bytes calculated including nullterm
2052 RtlOemStringToUnicodeSize(IN POEM_STRING OemString
)
2056 //this function returns size including nullterm
2057 RtlMultiByteToUnicodeSize(&Size
,
2071 RtlStringFromGUID (IN REFGUID Guid
,
2072 OUT PUNICODE_STRING GuidString
)
2074 STATIC CONST PWCHAR Hex
= L
"0123456789ABCDEF";
2081 return STATUS_INVALID_PARAMETER
;
2085 L
"{%08lX-%04X-%04X-%02X%02X-",
2091 BufferPtr
= Buffer
+ 25;
2094 for (i
= 2; i
< 8; i
++)
2096 *BufferPtr
++ = Hex
[Guid
->Data4
[i
] >> 4];
2097 *BufferPtr
++ = Hex
[Guid
->Data4
[i
] & 0xf];
2100 *BufferPtr
++ = L
'}';
2101 *BufferPtr
++ = L
'\0';
2103 return RtlCreateUnicodeString (GuidString
, Buffer
);
2111 * Bytes calculated including nullterm
2115 RtlUnicodeStringToAnsiSize(
2116 IN PUNICODE_STRING UnicodeString
)
2120 //this function return size without nullterm!
2121 RtlUnicodeToMultiByteSize (&Size
,
2122 UnicodeString
->Buffer
,
2123 UnicodeString
->Length
);
2125 return Size
+ sizeof(CHAR
); //NB: incl. nullterm
2136 RtlCompareUnicodeString(
2137 IN PUNICODE_STRING String1
,
2138 IN PUNICODE_STRING String2
,
2139 IN BOOLEAN CaseInsensitive
)
2145 if (String1
&& String2
)
2147 len1
= String1
->Length
/ sizeof(WCHAR
);
2148 len2
= String2
->Length
/ sizeof(WCHAR
);
2149 s1
= String1
->Buffer
;
2150 s2
= String2
->Buffer
;
2154 if (CaseInsensitive
)
2158 c1
= len1
-- ? RtlUpcaseUnicodeChar (*s1
++) : 0;
2159 c2
= len2
-- ? RtlUpcaseUnicodeChar (*s2
++) : 0;
2160 if (!c1
|| !c2
|| c1
!= c2
)
2168 c1
= len1
-- ? *s1
++ : 0;
2169 c2
= len2
-- ? *s2
++ : 0;
2170 if (!c1
|| !c2
|| c1
!= c2
)
2187 IN OUT PSTRING DestinationString
,
2188 IN PSTRING SourceString
)
2192 if(SourceString
== NULL
)
2194 DestinationString
->Length
= 0;
2198 copylen
= min (DestinationString
->MaximumLength
,
2199 SourceString
->Length
);
2201 memcpy(DestinationString
->Buffer
, SourceString
->Buffer
, copylen
);
2202 if (DestinationString
->MaximumLength
>= copylen
+ sizeof(CHAR
))
2204 DestinationString
->Buffer
[copylen
] = 0;
2206 DestinationString
->Length
= copylen
;
2216 RtlCopyUnicodeString(
2217 IN OUT PUNICODE_STRING DestinationString
,
2218 IN PUNICODE_STRING SourceString
)
2222 if (SourceString
== NULL
)
2224 DestinationString
->Length
= 0;
2228 copylen
= min (DestinationString
->MaximumLength
,
2229 SourceString
->Length
);
2230 memcpy(DestinationString
->Buffer
, SourceString
->Buffer
, copylen
);
2231 if (DestinationString
->MaximumLength
>= copylen
+ sizeof(WCHAR
))
2233 DestinationString
->Buffer
[copylen
/ sizeof(WCHAR
)] = 0;
2235 DestinationString
->Length
= copylen
;
2243 * See RtlpCreateUnicodeString
2247 RtlCreateUnicodeString(
2248 IN OUT PUNICODE_STRING UniDest
,
2252 DPRINT("RtlCreateUnicodeString\n");
2253 return RtlpCreateUnicodeString(UniDest
, Source
, NonPagedPool
);
2260 * Creates a nullterminated UNICODE_STRING
2264 RtlpCreateUnicodeString(
2265 IN OUT PUNICODE_STRING UniDest
,
2267 IN POOL_TYPE PoolType
)
2271 Length
= (wcslen (Source
) + 1) * sizeof(WCHAR
);
2273 UniDest
->Buffer
= ExAllocatePoolWithTag(PoolType
, Length
, TAG_USTR
);
2274 if (UniDest
->Buffer
== NULL
)
2277 memmove (UniDest
->Buffer
,
2281 UniDest
->MaximumLength
= Length
;
2282 UniDest
->Length
= Length
- sizeof (WCHAR
);
2294 RtlCreateUnicodeStringFromAsciiz(
2295 OUT PUNICODE_STRING Destination
,
2298 ANSI_STRING AnsiString
;
2301 RtlInitAnsiString (&AnsiString
,
2304 Status
= RtlAnsiStringToUnicodeString (Destination
,
2308 return NT_SUCCESS(Status
);
2317 * See RtlpDowncaseUnicodeString
2320 RtlDowncaseUnicodeString(
2321 IN OUT PUNICODE_STRING UniDest
,
2322 IN PUNICODE_STRING UniSource
,
2323 IN BOOLEAN AllocateDestinationString
)
2325 return RtlpDowncaseUnicodeString(
2328 AllocateDestinationString
,
2337 * Dest is never '\0' terminated because it may be equal to src, and src
2338 * might not be '\0' terminated.
2339 * Dest->Length is only set upon success.
2343 RtlpDowncaseUnicodeString(
2344 IN OUT PUNICODE_STRING UniDest
,
2345 IN PUNICODE_STRING UniSource
,
2346 IN BOOLEAN AllocateDestinationString
,
2347 IN POOL_TYPE PoolType
)
2352 if (AllocateDestinationString
)
2354 UniDest
->Buffer
= ExAllocatePoolWithTag(PoolType
, UniSource
->Length
, TAG_USTR
);
2355 if (UniDest
->Buffer
== NULL
)
2356 return STATUS_NO_MEMORY
;
2358 UniDest
->MaximumLength
= UniSource
->Length
;
2360 else if (UniSource
->Length
> UniDest
->MaximumLength
)
2362 return STATUS_BUFFER_TOO_SMALL
;
2365 UniDest
->Length
= UniSource
->Length
;
2367 Src
= UniSource
->Buffer
;
2368 Dest
= UniDest
->Buffer
;
2369 for (i
=0; i
< UniSource
->Length
/ sizeof(WCHAR
); i
++)
2375 else if (*Src
<= L
'Z')
2377 *Dest
= (*Src
+ (L
'a' - L
'A'));
2381 *Dest
= RtlDowncaseUnicodeChar(*Src
);
2388 return STATUS_SUCCESS
;
2397 * if src is NULL dest is unchanged.
2398 * dest is '\0' terminated when the MaximumLength allowes it.
2399 * When dest fits exactly in MaximumLength characters the '\0' is ommitted.
2402 RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination
,
2407 slen
= wcslen(Source
) * sizeof(WCHAR
);
2409 if (Destination
->Length
+ slen
> Destination
->MaximumLength
)
2410 return(STATUS_BUFFER_TOO_SMALL
);
2412 memcpy((char*)Destination
->Buffer
+ Destination
->Length
, Source
, slen
);
2413 Destination
->Length
+= slen
;
2414 /* append terminating '\0' if enough space */
2415 if( Destination
->MaximumLength
> Destination
->Length
)
2416 Destination
->Buffer
[Destination
->Length
/ sizeof(WCHAR
)] = 0;
2418 return(STATUS_SUCCESS
);
2426 * See RtlpAnsiStringToUnicodeString
2430 RtlAnsiStringToUnicodeString(
2431 IN OUT PUNICODE_STRING UniDest
,
2432 IN PANSI_STRING AnsiSource
,
2433 IN BOOLEAN AllocateDestinationString
)
2435 return RtlpAnsiStringToUnicodeString(
2438 AllocateDestinationString
,
2448 * This function always writes a terminating '\0'.
2449 * If the dest buffer is too small a partial copy is NOT performed!
2453 RtlpAnsiStringToUnicodeString(
2454 IN OUT PUNICODE_STRING UniDest
,
2455 IN PANSI_STRING AnsiSource
,
2456 IN BOOLEAN AllocateDestinationString
,
2457 IN POOL_TYPE PoolType
)
2460 ULONG Length
; //including nullterm
2462 if (NlsMbCodePageTag
== TRUE
)
2463 Length
= RtlAnsiStringToUnicodeSize(AnsiSource
);
2465 Length
= (AnsiSource
->Length
* sizeof(WCHAR
)) + sizeof(WCHAR
);
2467 if (Length
> 0xffff)
2468 return STATUS_INVALID_PARAMETER_2
;
2470 if (AllocateDestinationString
== TRUE
)
2472 UniDest
->Buffer
= ExAllocatePoolWithTag(PoolType
, Length
, TAG_USTR
);
2473 if (UniDest
->Buffer
== NULL
)
2474 return STATUS_NO_MEMORY
;
2476 UniDest
->MaximumLength
= Length
;
2478 else if (Length
> UniDest
->MaximumLength
)
2480 DPRINT("STATUS_BUFFER_TOO_SMALL\n");
2481 return STATUS_BUFFER_TOO_SMALL
;
2484 UniDest
->Length
= Length
- sizeof(WCHAR
);
2486 //FIXME: We don't need this??? -Gunnar
2487 RtlZeroMemory (UniDest
->Buffer
,
2490 Status
= RtlMultiByteToUnicodeN (UniDest
->Buffer
,
2494 AnsiSource
->Length
);
2496 if (!NT_SUCCESS(Status
) && AllocateDestinationString
)
2498 ExFreePoolWithTag(UniDest
->Buffer
, TAG_USTR
);
2502 UniDest
->Buffer
[UniDest
->Length
/ sizeof(WCHAR
)] = 0;
2512 * if src is NULL dest is unchanged.
2513 * dest is never '\0' terminated.
2517 RtlAppendAsciizToString(
2518 IN OUT PSTRING Destination
,
2525 return STATUS_SUCCESS
;
2527 Length
= strlen (Source
);
2528 if (Destination
->Length
+ Length
>= Destination
->MaximumLength
)
2529 return STATUS_BUFFER_TOO_SMALL
;
2531 Ptr
= Destination
->Buffer
+ Destination
->Length
;
2538 Destination
->Length
+= Length
;
2540 return STATUS_SUCCESS
;
2548 RtlUpperString(PSTRING DestinationString
,
2549 PSTRING SourceString
)
2556 Length
= min(SourceString
->Length
,
2557 DestinationString
->MaximumLength
- 1);
2559 Src
= SourceString
->Buffer
;
2560 Dest
= DestinationString
->Buffer
;
2561 for (i
= 0; i
< Length
; i
++)
2563 *Dest
= RtlUpperChar(*Src
);
2569 DestinationString
->Length
= SourceString
->Length
;
2577 RtlxAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString
)
2579 return RtlAnsiStringToUnicodeSize(AnsiString
);
2587 RtlxOemStringToUnicodeSize(IN POEM_STRING OemString
)
2589 return RtlOemStringToUnicodeSize((PANSI_STRING
)OemString
);
2598 RtlxUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString
)
2600 return RtlUnicodeStringToAnsiSize(UnicodeString
);
2608 RtlxUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString
)
2610 return RtlUnicodeStringToOemSize(UnicodeString
);
2618 * See RtlpDuplicateUnicodeString
2621 RtlDuplicateUnicodeString(
2623 IN PUNICODE_STRING SourceString
,
2624 PUNICODE_STRING DestinationString
)
2626 return RtlpDuplicateUnicodeString(
2638 RtlpDuplicateUnicodeString(
2640 IN PUNICODE_STRING SourceString
,
2641 PUNICODE_STRING DestinationString
,
2644 if (SourceString
== NULL
|| DestinationString
== NULL
)
2645 return STATUS_INVALID_PARAMETER
;
2648 if (SourceString
->Length
== 0 && AddNull
!= 3)
2650 DestinationString
->Length
= 0;
2651 DestinationString
->MaximumLength
= 0;
2652 DestinationString
->Buffer
= NULL
;
2656 unsigned int DestMaxLength
= SourceString
->Length
;
2659 DestMaxLength
+= sizeof(UNICODE_NULL
);
2661 DestinationString
->Buffer
= ExAllocatePool(PoolType
, DestMaxLength
);
2662 if (DestinationString
->Buffer
== NULL
)
2663 return STATUS_NO_MEMORY
;
2665 RtlCopyMemory(DestinationString
->Buffer
, SourceString
->Buffer
, SourceString
->Length
);
2666 DestinationString
->Length
= SourceString
->Length
;
2667 DestinationString
->MaximumLength
= DestMaxLength
;
2670 DestinationString
->Buffer
[DestinationString
->Length
/ sizeof(WCHAR
)] = 0;
2673 return STATUS_SUCCESS
;
2681 RtlValidateUnicodeString(IN ULONG Flags
,
2682 IN PUNICODE_STRING UnicodeString
)
2684 /* currently no flags are supported! */
2688 ((UnicodeString
== NULL
) ||
2689 ((UnicodeString
->Length
!= 0) &&
2690 (UnicodeString
->Buffer
!= NULL
) &&
2691 ((UnicodeString
->Length
% sizeof(WCHAR
)) == 0) &&
2692 ((UnicodeString
->MaximumLength
% sizeof(WCHAR
)) == 0) &&
2693 (UnicodeString
->MaximumLength
>= UnicodeString
->Length
))))
2695 /* a NULL pointer as a unicode string is considered to be a valid unicode
2697 return STATUS_SUCCESS
;
2701 return STATUS_INVALID_PARAMETER
;