2001-02-25 12:51:43 +00:00
|
|
|
/* $Id: unicode.c,v 1.17 2001/02/25 12:51:43 chorns Exp $
|
1999-11-15 16:02:50 +00:00
|
|
|
*
|
1999-01-16 21:03:00 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* FILE: ntoskrnl/rtl/unicode.c
|
|
|
|
* PURPOSE: String functions
|
|
|
|
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
|
|
|
|
* UPDATE HISTORY:
|
|
|
|
* Created 10/08/98
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <ddk/ntddk.h>
|
1999-11-15 16:02:50 +00:00
|
|
|
//#include <internal/nls.h>
|
2000-01-11 01:16:50 +00:00
|
|
|
#include <ctype.h>
|
2000-06-29 23:35:53 +00:00
|
|
|
#include <ntos/minmax.h>
|
1999-11-15 16:02:50 +00:00
|
|
|
|
1999-01-16 21:03:00 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <internal/debug.h>
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
|
|
|
WCHAR
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlAnsiCharToUnicodeChar(CHAR AnsiChar)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-15 16:02:50 +00:00
|
|
|
ULONG Size;
|
|
|
|
WCHAR UnicodeChar;
|
|
|
|
|
|
|
|
Size = 1;
|
|
|
|
#if 0
|
1999-11-20 21:49:23 +00:00
|
|
|
Size = (NlsLeadByteInfo[AnsiChar] == 0) ? 1 : 2;
|
1999-11-15 16:02:50 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
RtlMultiByteToUnicodeN (&UnicodeChar,
|
|
|
|
sizeof(WCHAR),
|
|
|
|
NULL,
|
1999-11-20 21:49:23 +00:00
|
|
|
&AnsiChar,
|
1999-11-15 16:02:50 +00:00
|
|
|
Size);
|
|
|
|
|
|
|
|
return UnicodeChar;
|
1999-01-16 21:03:00 +00:00
|
|
|
}
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
|
|
|
|
ULONG
|
|
|
|
STDCALL
|
|
|
|
RtlAnsiStringToUnicodeSize(PANSI_STRING AnsiString)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-15 16:02:50 +00:00
|
|
|
ULONG Size;
|
|
|
|
|
|
|
|
RtlMultiByteToUnicodeSize (&Size,
|
|
|
|
AnsiString->Buffer,
|
|
|
|
AnsiString->Length);
|
|
|
|
|
|
|
|
return Size;
|
1999-01-16 21:03:00 +00:00
|
|
|
}
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlAnsiStringToUnicodeString (
|
|
|
|
PUNICODE_STRING DestinationString,
|
|
|
|
PANSI_STRING SourceString,
|
|
|
|
BOOLEAN AllocateDestinationString
|
|
|
|
)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-15 16:02:50 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG Length;
|
|
|
|
|
|
|
|
if (NlsMbCodePageTag == TRUE)
|
|
|
|
Length = RtlAnsiStringToUnicodeSize (SourceString);
|
|
|
|
else
|
|
|
|
Length = SourceString->Length * sizeof(WCHAR);
|
|
|
|
|
|
|
|
if (Length > 65535)
|
|
|
|
return STATUS_INVALID_PARAMETER_2;
|
|
|
|
|
|
|
|
if (AllocateDestinationString == TRUE)
|
|
|
|
{
|
|
|
|
DestinationString->MaximumLength = Length + sizeof(WCHAR);
|
|
|
|
DestinationString->Buffer =
|
|
|
|
ExAllocatePool (NonPagedPool,
|
|
|
|
DestinationString->MaximumLength);
|
|
|
|
if (DestinationString->Buffer == NULL)
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-12-10 17:49:21 +00:00
|
|
|
if (Length > DestinationString->MaximumLength)
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
1999-12-10 17:49:21 +00:00
|
|
|
DestinationString->Length = Length;
|
1999-11-15 16:02:50 +00:00
|
|
|
|
1999-12-10 17:49:21 +00:00
|
|
|
RtlZeroMemory (DestinationString->Buffer,
|
|
|
|
DestinationString->Length);
|
1999-11-15 16:02:50 +00:00
|
|
|
|
|
|
|
Status = RtlMultiByteToUnicodeN (DestinationString->Buffer,
|
|
|
|
DestinationString->Length,
|
|
|
|
NULL,
|
|
|
|
SourceString->Buffer,
|
|
|
|
SourceString->Length);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (AllocateDestinationString)
|
|
|
|
ExFreePool (DestinationString->Buffer);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlAppendAsciizToString (
|
|
|
|
IN OUT PSTRING Destination,
|
|
|
|
IN PCSZ Source
|
|
|
|
)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
|
|
|
ULONG Length;
|
|
|
|
PCHAR Ptr;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
if (Source == NULL)
|
|
|
|
return STATUS_SUCCESS;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
Length = strlen (Source);
|
|
|
|
if (Destination->Length + Length >= Destination->MaximumLength)
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
Ptr = Destination->Buffer + Destination->Length;
|
|
|
|
memmove (Ptr,
|
|
|
|
Source,
|
|
|
|
Length);
|
|
|
|
Ptr += Length;
|
|
|
|
*Ptr = 0;
|
|
|
|
|
|
|
|
Destination->Length += Length;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlAppendStringToString (
|
|
|
|
PSTRING Destination,
|
|
|
|
PSTRING Source
|
|
|
|
)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
|
|
|
PCHAR Ptr;
|
|
|
|
|
|
|
|
if (Source->Length == 0)
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
|
|
|
if (Destination->Length + Source->Length >= Destination->MaximumLength)
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
|
|
|
|
|
|
|
Ptr = Destination->Buffer + Destination->Length;
|
|
|
|
memmove (Ptr,
|
|
|
|
Source->Buffer,
|
|
|
|
Source->Length);
|
|
|
|
Ptr += Source->Length;
|
|
|
|
*Ptr = 0;
|
|
|
|
|
|
|
|
Destination->Length += Source->Length;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlAppendUnicodeStringToString (
|
|
|
|
IN OUT PUNICODE_STRING Destination,
|
|
|
|
IN PUNICODE_STRING Source
|
|
|
|
)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-15 16:02:50 +00:00
|
|
|
PWCHAR Src, Dest;
|
|
|
|
ULONG i;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
if ((Source->Length + Destination->Length) >= Destination->MaximumLength)
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
Src = Source->Buffer;
|
|
|
|
Dest = Destination->Buffer + (Destination->Length / sizeof (WCHAR));
|
|
|
|
for (i = 0; i < (Source->Length / sizeof(WCHAR)); i++)
|
|
|
|
{
|
|
|
|
*Dest = *Src;
|
|
|
|
Dest++;
|
|
|
|
Src++;
|
|
|
|
}
|
|
|
|
*Dest = 0;
|
|
|
|
|
|
|
|
Destination->Length += Source->Length;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlAppendUnicodeToString (
|
|
|
|
IN OUT PUNICODE_STRING Destination,
|
|
|
|
IN PWSTR Source
|
|
|
|
)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-15 16:02:50 +00:00
|
|
|
PWCHAR Src;
|
|
|
|
PWCHAR Dest;
|
|
|
|
ULONG i;
|
|
|
|
ULONG slen;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
slen = wcslen (Source);
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
if (Destination->Length + slen >= Destination->MaximumLength)
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
Src = Source;
|
|
|
|
Dest = Destination->Buffer + (Destination->Length / sizeof (WCHAR));
|
|
|
|
|
|
|
|
for (i = 0; i < slen; i++)
|
|
|
|
{
|
|
|
|
*Dest = *Src;
|
|
|
|
Dest++;
|
|
|
|
Src++;
|
|
|
|
}
|
|
|
|
*Dest = 0;
|
|
|
|
|
|
|
|
Destination->Length += (slen * sizeof(WCHAR));
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
|
|
|
RtlCharToInteger(IN PCSZ String, IN ULONG Base, IN OUT PULONG Value)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
2000-01-11 01:16:50 +00:00
|
|
|
ULONG Val;
|
|
|
|
|
|
|
|
*Value = 0;
|
|
|
|
|
|
|
|
if (Base == 0)
|
|
|
|
{
|
|
|
|
Base = 10;
|
|
|
|
if (*String == '0')
|
|
|
|
{
|
|
|
|
Base = 8;
|
|
|
|
String++;
|
|
|
|
if ((*String == 'x') && isxdigit (String[1]))
|
|
|
|
{
|
|
|
|
String++;
|
|
|
|
Base = 16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!isxdigit (*String))
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
while (isxdigit (*String) &&
|
|
|
|
(Val = isdigit (*String) ? * String - '0' : (islower (*String)
|
|
|
|
? toupper (*String) : *String) - 'A' + 10) < Base)
|
|
|
|
{
|
|
|
|
*Value = *Value * Base + Val;
|
|
|
|
String++;
|
|
|
|
}
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
return STATUS_SUCCESS;
|
1999-03-25 00:37:06 +00:00
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
LONG
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlCompareString (
|
2000-02-19 19:31:41 +00:00
|
|
|
IN PSTRING String1,
|
|
|
|
IN PSTRING String2,
|
|
|
|
IN BOOLEAN CaseInsensitive
|
1999-11-20 21:49:23 +00:00
|
|
|
)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
2000-02-19 19:31:41 +00:00
|
|
|
ULONG len1, len2;
|
|
|
|
PCHAR s1, s2;
|
|
|
|
CHAR c1, c2;
|
1999-11-15 16:02:50 +00:00
|
|
|
|
2000-02-19 19:31:41 +00:00
|
|
|
if (String1 && String2)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
2000-02-19 19:31:41 +00:00
|
|
|
len1 = String1->Length;
|
|
|
|
len2 = String2->Length;
|
|
|
|
s1 = String1->Buffer;
|
|
|
|
s2 = String2->Buffer;
|
1999-11-15 16:02:50 +00:00
|
|
|
|
2000-02-19 19:31:41 +00:00
|
|
|
if (s1 && s2)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
2000-02-19 19:31:41 +00:00
|
|
|
if (CaseInsensitive)
|
|
|
|
{
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
c1 = len1-- ? RtlUpperChar (*s1++) : 0;
|
|
|
|
c2 = len2-- ? RtlUpperChar (*s2++) : 0;
|
|
|
|
if (!c1 || !c2 || c1 != c2)
|
|
|
|
return c1 - c2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
c1 = len1-- ? *s1++ : 0;
|
|
|
|
c2 = len2-- ? *s2++ : 0;
|
|
|
|
if (!c1 || !c2 || c1 != c2)
|
|
|
|
return c1 - c2;
|
|
|
|
}
|
|
|
|
}
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LONG
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlCompareUnicodeString (
|
2000-02-19 19:31:41 +00:00
|
|
|
IN PUNICODE_STRING String1,
|
|
|
|
IN PUNICODE_STRING String2,
|
|
|
|
IN BOOLEAN CaseInsensitive
|
1999-11-20 21:49:23 +00:00
|
|
|
)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
2000-02-19 19:31:41 +00:00
|
|
|
ULONG len1, len2;
|
|
|
|
PWCHAR s1, s2;
|
|
|
|
WCHAR c1, c2;
|
1999-11-15 16:02:50 +00:00
|
|
|
|
2000-02-19 19:31:41 +00:00
|
|
|
if (String1 && String2)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
2000-02-19 19:31:41 +00:00
|
|
|
len1 = String1->Length / sizeof(WCHAR);
|
|
|
|
len2 = String2->Length / sizeof(WCHAR);
|
|
|
|
s1 = String1->Buffer;
|
|
|
|
s2 = String2->Buffer;
|
|
|
|
|
|
|
|
if (s1 && s2)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
2000-02-19 19:31:41 +00:00
|
|
|
if (CaseInsensitive)
|
|
|
|
{
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
c1 = len1-- ? RtlUpcaseUnicodeChar (*s1++) : 0;
|
|
|
|
c2 = len2-- ? RtlUpcaseUnicodeChar (*s2++) : 0;
|
|
|
|
if (!c1 || !c2 || c1 != c2)
|
|
|
|
return c1 - c2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
c1 = len1-- ? *s1++ : 0;
|
|
|
|
c2 = len2-- ? *s2++ : 0;
|
|
|
|
if (!c1 || !c2 || c1 != c2)
|
|
|
|
return c1 - c2;
|
|
|
|
}
|
|
|
|
}
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
VOID
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlCopyString (
|
|
|
|
IN OUT PSTRING DestinationString,
|
|
|
|
IN PSTRING SourceString
|
|
|
|
)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-20 21:49:23 +00:00
|
|
|
ULONG copylen, i;
|
|
|
|
PCHAR Src, Dest;
|
1999-11-15 16:02:50 +00:00
|
|
|
|
|
|
|
if(SourceString == NULL)
|
|
|
|
{
|
|
|
|
DestinationString->Length = 0;
|
1999-11-20 21:49:23 +00:00
|
|
|
return;
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
copylen = min (DestinationString->MaximumLength - sizeof(CHAR),
|
|
|
|
SourceString->Length);
|
|
|
|
Src = SourceString->Buffer;
|
|
|
|
Dest = DestinationString->Buffer;
|
1999-11-15 16:02:50 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
for (i = 0; i < copylen; i++)
|
|
|
|
{
|
|
|
|
*Dest = *Src;
|
|
|
|
Dest++;
|
|
|
|
Src++;
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
1999-11-20 21:49:23 +00:00
|
|
|
*Dest = 0;
|
|
|
|
|
|
|
|
DestinationString->Length = copylen;
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
VOID
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlCopyUnicodeString (
|
|
|
|
IN OUT PUNICODE_STRING DestinationString,
|
|
|
|
IN PUNICODE_STRING SourceString
|
|
|
|
)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
1999-11-20 21:49:23 +00:00
|
|
|
ULONG copylen, i;
|
1999-11-15 16:02:50 +00:00
|
|
|
PWCHAR Src, Dest;
|
|
|
|
|
|
|
|
if(SourceString==NULL)
|
|
|
|
{
|
|
|
|
DestinationString->Length=0;
|
1999-11-20 21:49:23 +00:00
|
|
|
return;
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
copylen = min(DestinationString->MaximumLength - sizeof(WCHAR),
|
|
|
|
SourceString->Length);
|
|
|
|
Src = SourceString->Buffer;
|
|
|
|
Dest = DestinationString->Buffer;
|
1999-11-15 16:02:50 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
for (i = 0; i < (copylen / sizeof (WCHAR)); i++)
|
|
|
|
{
|
|
|
|
*Dest = *Src;
|
|
|
|
Dest++;
|
|
|
|
Src++;
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
1999-11-20 21:49:23 +00:00
|
|
|
*Dest = 0;
|
|
|
|
|
|
|
|
DestinationString->Length = copylen;
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
BOOLEAN
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlCreateUnicodeString (
|
|
|
|
IN OUT PUNICODE_STRING Destination,
|
|
|
|
IN PWSTR Source
|
|
|
|
)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-15 16:02:50 +00:00
|
|
|
ULONG Length;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
Length = (wcslen (Source) + 1) * sizeof(WCHAR);
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
Destination->Buffer = ExAllocatePool (NonPagedPool,
|
|
|
|
Length);
|
|
|
|
if (Destination->Buffer == NULL)
|
|
|
|
return FALSE;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
memmove (Destination->Buffer,
|
|
|
|
Source,
|
|
|
|
Length);
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
Destination->MaximumLength = Length;
|
|
|
|
Destination->Length = Length - sizeof (WCHAR);
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
BOOLEAN
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlCreateUnicodeStringFromAsciiz (
|
|
|
|
IN OUT PUNICODE_STRING Destination,
|
|
|
|
IN PCSZ Source
|
|
|
|
)
|
|
|
|
{
|
|
|
|
ANSI_STRING AnsiString;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
RtlInitAnsiString (&AnsiString,
|
|
|
|
Source);
|
|
|
|
|
|
|
|
Status = RtlAnsiStringToUnicodeString (Destination,
|
|
|
|
&AnsiString,
|
|
|
|
TRUE);
|
|
|
|
|
|
|
|
return NT_SUCCESS(Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
|
|
|
RtlDowncaseUnicodeString (
|
|
|
|
IN OUT PUNICODE_STRING DestinationString,
|
|
|
|
IN PUNICODE_STRING SourceString,
|
|
|
|
IN BOOLEAN AllocateDestinationString
|
|
|
|
)
|
|
|
|
{
|
|
|
|
ULONG i;
|
|
|
|
PWCHAR Src, Dest;
|
|
|
|
|
|
|
|
if (AllocateDestinationString == TRUE)
|
|
|
|
{
|
|
|
|
DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR);
|
|
|
|
DestinationString->Buffer = ExAllocatePool (NonPagedPool,
|
|
|
|
SourceString->Length + sizeof(WCHAR));
|
|
|
|
if (DestinationString->Buffer == NULL)
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (SourceString->Length >= DestinationString->MaximumLength)
|
1999-12-10 17:49:21 +00:00
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
1999-11-20 21:49:23 +00:00
|
|
|
}
|
1999-12-10 17:49:21 +00:00
|
|
|
DestinationString->Length = SourceString->Length;
|
1999-11-20 21:49:23 +00:00
|
|
|
|
|
|
|
Src = SourceString->Buffer;
|
|
|
|
Dest = DestinationString->Buffer;
|
|
|
|
for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
|
|
|
|
{
|
|
|
|
if (*Src < L'A')
|
|
|
|
{
|
|
|
|
*Dest = *Src;
|
|
|
|
}
|
|
|
|
else if (*Src <= L'Z')
|
|
|
|
{
|
|
|
|
*Dest = (*Src + (L'a' - L'A'));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* FIXME: characters above 'Z' */
|
|
|
|
*Dest = *Src;
|
|
|
|
}
|
|
|
|
|
|
|
|
Dest++;
|
|
|
|
Src++;
|
|
|
|
}
|
|
|
|
*Dest = 0;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
STDCALL
|
|
|
|
RtlEqualString (
|
|
|
|
IN PSTRING String1,
|
|
|
|
IN PSTRING String2,
|
|
|
|
IN BOOLEAN CaseInsensitive
|
|
|
|
)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-15 16:02:50 +00:00
|
|
|
unsigned long s1l=String1->Length;
|
|
|
|
unsigned long s2l=String2->Length;
|
|
|
|
unsigned long i;
|
|
|
|
char c1, c2;
|
|
|
|
|
|
|
|
if (s1l != s2l)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
for (i = 0; i < s1l; i++)
|
|
|
|
{
|
|
|
|
c1 = *String1->Buffer;
|
|
|
|
c2 = *String2->Buffer;
|
|
|
|
|
|
|
|
if (CaseInsensitive == TRUE)
|
|
|
|
{
|
1999-11-20 21:49:23 +00:00
|
|
|
c1 = RtlUpperChar (c1);
|
|
|
|
c2 = RtlUpperChar (c2);
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (c1 != c2)
|
|
|
|
{
|
|
|
|
String1->Buffer -= i;
|
|
|
|
String2->Buffer -= i;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
String1->Buffer++;
|
|
|
|
String2->Buffer++;
|
|
|
|
}
|
|
|
|
|
|
|
|
String1->Buffer -= i;
|
|
|
|
String2->Buffer -= i;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlEqualUnicodeString (
|
|
|
|
IN PUNICODE_STRING String1,
|
|
|
|
IN PUNICODE_STRING String2,
|
|
|
|
IN BOOLEAN CaseInsensitive
|
|
|
|
)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-15 16:02:50 +00:00
|
|
|
unsigned long s1l = String1->Length / sizeof(WCHAR);
|
|
|
|
unsigned long s2l = String2->Length / sizeof(WCHAR);
|
|
|
|
unsigned long i;
|
|
|
|
WCHAR wc1, wc2;
|
|
|
|
PWCHAR pw1, pw2;
|
|
|
|
|
|
|
|
if (s1l != s2l)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
pw1 = String1->Buffer;
|
|
|
|
pw2 = String2->Buffer;
|
|
|
|
|
|
|
|
for (i = 0; i < s1l; i++)
|
|
|
|
{
|
|
|
|
if(CaseInsensitive == TRUE)
|
|
|
|
{
|
1999-11-20 21:49:23 +00:00
|
|
|
wc1 = RtlUpcaseUnicodeChar (*pw1);
|
|
|
|
wc2 = RtlUpcaseUnicodeChar (*pw2);
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
wc1 = *pw1;
|
|
|
|
wc2 = *pw2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (wc1 != wc2)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
pw1++;
|
|
|
|
pw2++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
|
|
|
|
VOID
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlFreeAnsiString (
|
|
|
|
IN PANSI_STRING AnsiString
|
|
|
|
)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-15 16:02:50 +00:00
|
|
|
if (AnsiString->Buffer == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ExFreePool (AnsiString->Buffer);
|
|
|
|
|
|
|
|
AnsiString->Buffer = NULL;
|
|
|
|
AnsiString->Length = 0;
|
|
|
|
AnsiString->MaximumLength = 0;
|
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
VOID
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlFreeOemString (
|
|
|
|
IN POEM_STRING OemString
|
|
|
|
)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-15 16:02:50 +00:00
|
|
|
if (OemString->Buffer == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ExFreePool (OemString->Buffer);
|
|
|
|
|
|
|
|
OemString->Buffer = NULL;
|
|
|
|
OemString->Length = 0;
|
|
|
|
OemString->MaximumLength = 0;
|
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
|
|
|
|
VOID
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlFreeUnicodeString (
|
|
|
|
IN PUNICODE_STRING UnicodeString
|
|
|
|
)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-15 16:02:50 +00:00
|
|
|
if (UnicodeString->Buffer == NULL)
|
|
|
|
return;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
ExFreePool (UnicodeString->Buffer);
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
UnicodeString->Buffer = NULL;
|
|
|
|
UnicodeString->Length = 0;
|
|
|
|
UnicodeString->MaximumLength = 0;
|
1999-01-16 21:03:00 +00:00
|
|
|
}
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
|
|
|
|
VOID
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlInitAnsiString (
|
|
|
|
IN OUT PANSI_STRING DestinationString,
|
|
|
|
IN PCSZ SourceString
|
|
|
|
)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
|
|
|
ULONG DestSize;
|
|
|
|
|
|
|
|
if (SourceString == NULL)
|
|
|
|
{
|
|
|
|
DestinationString->Length = 0;
|
|
|
|
DestinationString->MaximumLength = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DestSize = strlen ((const char *)SourceString);
|
|
|
|
DestinationString->Length = DestSize;
|
|
|
|
DestinationString->MaximumLength = DestSize + sizeof(CHAR);
|
|
|
|
}
|
|
|
|
DestinationString->Buffer = (PCHAR)SourceString;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlInitString (
|
|
|
|
IN OUT PSTRING DestinationString,
|
|
|
|
IN PCSZ SourceString
|
|
|
|
)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
|
|
|
ULONG DestSize;
|
|
|
|
|
|
|
|
if (SourceString == NULL)
|
|
|
|
{
|
|
|
|
DestinationString->Length = 0;
|
|
|
|
DestinationString->MaximumLength = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DestSize = strlen((const char *)SourceString);
|
|
|
|
DestinationString->Length = DestSize;
|
|
|
|
DestinationString->MaximumLength = DestSize + sizeof(CHAR);
|
|
|
|
}
|
|
|
|
DestinationString->Buffer = (PCHAR)SourceString;
|
|
|
|
}
|
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
VOID
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlInitUnicodeString (
|
|
|
|
IN OUT PUNICODE_STRING DestinationString,
|
|
|
|
IN PCWSTR SourceString
|
|
|
|
)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-15 16:02:50 +00:00
|
|
|
ULONG DestSize;
|
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
DPRINT("RtlInitUnicodeString(DestinationString %x, SourceString %x)\n",
|
|
|
|
DestinationString,
|
|
|
|
SourceString);
|
1999-11-15 16:02:50 +00:00
|
|
|
|
|
|
|
if (SourceString == NULL)
|
|
|
|
{
|
|
|
|
DestinationString->Length = 0;
|
|
|
|
DestinationString->MaximumLength = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DestSize = wcslen((PWSTR)SourceString) * sizeof(WCHAR);
|
|
|
|
DestinationString->Length = DestSize;
|
|
|
|
DestinationString->MaximumLength = DestSize + sizeof(WCHAR);
|
|
|
|
}
|
|
|
|
DestinationString->Buffer = (PWSTR)SourceString;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlIntegerToChar (
|
|
|
|
IN ULONG Value,
|
|
|
|
IN ULONG Base,
|
|
|
|
IN ULONG Length,
|
|
|
|
IN OUT PCHAR String
|
|
|
|
)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
1999-11-20 21:49:23 +00:00
|
|
|
ULONG Radix;
|
|
|
|
CHAR temp[33];
|
|
|
|
ULONG v = 0;
|
|
|
|
ULONG i;
|
|
|
|
PCHAR tp;
|
|
|
|
PCHAR sp;
|
1999-11-15 16:02:50 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
Radix = Base;
|
|
|
|
if (Radix == 0)
|
|
|
|
Radix = 10;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
if ((Radix != 2) && (Radix != 8) &&
|
|
|
|
(Radix != 10) && (Radix != 16))
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
tp = temp;
|
|
|
|
while (v || tp == temp)
|
|
|
|
{
|
|
|
|
i = v % Radix;
|
|
|
|
v = v / Radix;
|
|
|
|
if (i < 10)
|
|
|
|
*tp = i + '0';
|
|
|
|
else
|
|
|
|
*tp = i + 'a' - 10;
|
|
|
|
tp++;
|
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
if (tp - temp >= Length)
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
sp = String;
|
|
|
|
while (tp > temp)
|
|
|
|
*sp++ = *--tp;
|
|
|
|
*sp = 0;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
|
|
|
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
|
|
|
RtlIntegerToUnicodeString (
|
|
|
|
IN ULONG Value,
|
|
|
|
IN ULONG Base, /* optional */
|
|
|
|
IN OUT PUNICODE_STRING String
|
|
|
|
)
|
|
|
|
{
|
|
|
|
ANSI_STRING AnsiString;
|
|
|
|
CHAR Buffer[33];
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = RtlIntegerToChar (Value,
|
|
|
|
Base,
|
|
|
|
33,
|
|
|
|
Buffer);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
|
|
|
|
|
|
|
AnsiString.Buffer = Buffer;
|
|
|
|
AnsiString.Length = strlen (Buffer);
|
|
|
|
AnsiString.MaximumLength = 33;
|
|
|
|
|
|
|
|
Status = RtlAnsiStringToUnicodeString (String,
|
|
|
|
&AnsiString,
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-03-03 00:48:50 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
|
|
|
RtlOemStringToCountedUnicodeString (
|
|
|
|
IN OUT PUNICODE_STRING DestinationString,
|
|
|
|
IN POEM_STRING SourceString,
|
|
|
|
IN BOOLEAN AllocateDestinationString
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG Length;
|
|
|
|
|
|
|
|
if (NlsMbCodePageTag == TRUE)
|
|
|
|
Length = RtlAnsiStringToUnicodeSize (SourceString);
|
|
|
|
else
|
|
|
|
Length = SourceString->Length * sizeof(WCHAR);
|
|
|
|
|
|
|
|
if (Length > 65535)
|
|
|
|
return STATUS_INVALID_PARAMETER_2;
|
|
|
|
|
|
|
|
if (AllocateDestinationString == TRUE)
|
|
|
|
{
|
|
|
|
DestinationString->MaximumLength = Length + sizeof(WCHAR);
|
|
|
|
DestinationString->Buffer =
|
|
|
|
ExAllocatePool (NonPagedPool,
|
|
|
|
DestinationString->MaximumLength);
|
|
|
|
if (DestinationString->Buffer == NULL)
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (Length > DestinationString->MaximumLength)
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
|
|
|
}
|
|
|
|
DestinationString->Length = Length;
|
|
|
|
|
|
|
|
RtlZeroMemory (DestinationString->Buffer,
|
|
|
|
DestinationString->Length);
|
|
|
|
|
|
|
|
Status = RtlOemToUnicodeN (DestinationString->Buffer,
|
|
|
|
DestinationString->Length,
|
|
|
|
NULL,
|
|
|
|
SourceString->Buffer,
|
|
|
|
SourceString->Length);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (AllocateDestinationString)
|
|
|
|
ExFreePool (DestinationString->Buffer);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
1999-11-20 21:49:23 +00:00
|
|
|
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
ULONG
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlOemStringToUnicodeSize (
|
|
|
|
IN POEM_STRING OemString
|
|
|
|
)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-15 16:02:50 +00:00
|
|
|
ULONG Size;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
RtlMultiByteToUnicodeSize (&Size,
|
|
|
|
OemString->Buffer,
|
|
|
|
OemString->Length);
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
return Size;
|
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlOemStringToUnicodeString (
|
|
|
|
IN OUT PUNICODE_STRING DestinationString,
|
|
|
|
IN POEM_STRING SourceString,
|
|
|
|
IN BOOLEAN AllocateDestinationString
|
|
|
|
)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG Length;
|
|
|
|
|
|
|
|
if (NlsMbCodePageTag == TRUE)
|
|
|
|
Length = RtlAnsiStringToUnicodeSize (SourceString);
|
|
|
|
else
|
|
|
|
Length = SourceString->Length * sizeof(WCHAR);
|
|
|
|
|
|
|
|
if (Length > 65535)
|
|
|
|
return STATUS_INVALID_PARAMETER_2;
|
|
|
|
|
|
|
|
if (AllocateDestinationString == TRUE)
|
|
|
|
{
|
|
|
|
DestinationString->MaximumLength = Length + sizeof(WCHAR);
|
|
|
|
DestinationString->Buffer =
|
|
|
|
ExAllocatePool (NonPagedPool,
|
|
|
|
DestinationString->MaximumLength);
|
|
|
|
if (DestinationString->Buffer == NULL)
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-12-10 17:49:21 +00:00
|
|
|
if (Length >= DestinationString->MaximumLength)
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
1999-12-10 17:49:21 +00:00
|
|
|
DestinationString->Length = Length;
|
1999-11-15 16:02:50 +00:00
|
|
|
|
1999-12-10 17:49:21 +00:00
|
|
|
RtlZeroMemory (DestinationString->Buffer,
|
|
|
|
DestinationString->Length);
|
1999-11-15 16:02:50 +00:00
|
|
|
|
|
|
|
Status = RtlOemToUnicodeN (DestinationString->Buffer,
|
|
|
|
DestinationString->Length,
|
|
|
|
NULL,
|
|
|
|
SourceString->Buffer,
|
|
|
|
SourceString->Length);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (AllocateDestinationString)
|
|
|
|
ExFreePool (DestinationString->Buffer);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
DestinationString->Buffer[Length / sizeof(WCHAR)] = 0;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
|
|
|
|
2000-04-15 23:14:32 +00:00
|
|
|
BOOLEAN
|
|
|
|
STDCALL
|
|
|
|
RtlPrefixString (
|
|
|
|
PANSI_STRING String1,
|
|
|
|
PANSI_STRING String2,
|
|
|
|
BOOLEAN CaseInsensitive
|
|
|
|
)
|
|
|
|
{
|
|
|
|
PCHAR pc1;
|
|
|
|
PCHAR pc2;
|
|
|
|
ULONG Length;
|
|
|
|
|
|
|
|
if (String2->Length < String1->Length)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
Length = String1->Length;
|
|
|
|
pc1 = String1->Buffer;
|
|
|
|
pc2 = String2->Buffer;
|
|
|
|
|
|
|
|
if (pc1 && pc2)
|
|
|
|
{
|
|
|
|
if (CaseInsensitive)
|
|
|
|
{
|
|
|
|
while (Length--)
|
|
|
|
{
|
|
|
|
if (RtlUpperChar (*pc1++) != RtlUpperChar (*pc2++))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (Length--)
|
|
|
|
{
|
|
|
|
if (*pc1++ != *pc2++)
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
STDCALL
|
|
|
|
RtlPrefixUnicodeString (
|
|
|
|
PUNICODE_STRING String1,
|
|
|
|
PUNICODE_STRING String2,
|
|
|
|
BOOLEAN CaseInsensitive
|
|
|
|
)
|
|
|
|
{
|
|
|
|
PWCHAR pc1;
|
|
|
|
PWCHAR pc2;
|
|
|
|
ULONG Length;
|
|
|
|
|
|
|
|
if (String2->Length < String1->Length)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
Length = String1->Length / 2;
|
|
|
|
pc1 = String1->Buffer;
|
|
|
|
pc2 = String2->Buffer;
|
|
|
|
|
|
|
|
if (pc1 && pc2)
|
|
|
|
{
|
|
|
|
if (CaseInsensitive)
|
|
|
|
{
|
|
|
|
while (Length--)
|
|
|
|
{
|
|
|
|
if (RtlUpcaseUnicodeChar (*pc1++)
|
|
|
|
!= RtlUpcaseUnicodeChar (*pc2++))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (Length--)
|
|
|
|
{
|
|
|
|
if( *pc1++ != *pc2++ )
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
ULONG
|
|
|
|
STDCALL
|
|
|
|
RtlUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString)
|
|
|
|
{
|
|
|
|
ULONG Size;
|
|
|
|
|
|
|
|
RtlUnicodeToMultiByteSize (&Size,
|
|
|
|
UnicodeString->Buffer,
|
|
|
|
UnicodeString->Length);
|
|
|
|
|
|
|
|
return Size;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlUnicodeStringToAnsiString (
|
|
|
|
IN OUT PANSI_STRING DestinationString,
|
|
|
|
IN PUNICODE_STRING SourceString,
|
|
|
|
IN BOOLEAN AllocateDestinationString
|
|
|
|
)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG Length;
|
|
|
|
|
|
|
|
if (NlsMbCodePageTag == TRUE)
|
|
|
|
Length = RtlUnicodeStringToAnsiSize (SourceString);
|
|
|
|
else
|
|
|
|
Length = SourceString->Length / sizeof(WCHAR);
|
|
|
|
|
|
|
|
if (AllocateDestinationString == TRUE)
|
|
|
|
{
|
|
|
|
DestinationString->MaximumLength = Length + sizeof(CHAR);
|
2000-01-11 01:16:50 +00:00
|
|
|
DestinationString->Buffer =
|
|
|
|
ExAllocatePool (NonPagedPool,
|
|
|
|
DestinationString->MaximumLength);
|
1999-11-15 16:02:50 +00:00
|
|
|
if (DestinationString->Buffer == NULL)
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-12-10 17:49:21 +00:00
|
|
|
if (Length >= DestinationString->MaximumLength)
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
1999-12-10 17:49:21 +00:00
|
|
|
DestinationString->Length = Length;
|
1999-11-15 16:02:50 +00:00
|
|
|
|
|
|
|
RtlZeroMemory (DestinationString->Buffer,
|
|
|
|
DestinationString->Length);
|
|
|
|
|
|
|
|
Status = RtlUnicodeToMultiByteN (DestinationString->Buffer,
|
|
|
|
DestinationString->Length,
|
|
|
|
NULL,
|
|
|
|
SourceString->Buffer,
|
|
|
|
SourceString->Length);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (AllocateDestinationString)
|
|
|
|
ExFreePool (DestinationString->Buffer);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
DestinationString->Buffer[Length] = 0;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
1999-01-16 21:03:00 +00:00
|
|
|
|
2000-03-03 00:48:50 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
|
|
|
RtlUnicodeStringToCountedOemString (
|
|
|
|
IN OUT POEM_STRING DestinationString,
|
|
|
|
IN PUNICODE_STRING SourceString,
|
|
|
|
IN BOOLEAN AllocateDestinationString
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG Length;
|
|
|
|
ULONG Size;
|
|
|
|
|
|
|
|
if (NlsMbOemCodePageTag == TRUE)
|
|
|
|
Length = RtlUnicodeStringToAnsiSize (SourceString) + 1;
|
|
|
|
else
|
|
|
|
Length = SourceString->Length / sizeof(WCHAR) + 1;
|
|
|
|
|
|
|
|
if (Length > 0x0000FFFF)
|
|
|
|
return STATUS_INVALID_PARAMETER_2;
|
|
|
|
|
|
|
|
DestinationString->Length = (WORD)(Length - 1);
|
|
|
|
|
|
|
|
if (AllocateDestinationString)
|
|
|
|
{
|
|
|
|
DestinationString->Buffer = ExAllocatePool (NonPagedPool,
|
|
|
|
Length);
|
|
|
|
|
|
|
|
if (DestinationString->Buffer == NULL)
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
|
|
|
|
RtlZeroMemory (DestinationString->Buffer,
|
|
|
|
Length);
|
|
|
|
DestinationString->MaximumLength = (WORD)Length;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (Length > DestinationString->MaximumLength)
|
|
|
|
{
|
|
|
|
if (DestinationString->MaximumLength == 0)
|
|
|
|
return STATUS_BUFFER_OVERFLOW;
|
|
|
|
DestinationString->Length =
|
|
|
|
DestinationString->MaximumLength - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = RtlUnicodeToOemN (DestinationString->Buffer,
|
|
|
|
DestinationString->Length,
|
|
|
|
&Size,
|
|
|
|
SourceString->Buffer,
|
|
|
|
SourceString->Length);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (AllocateDestinationString)
|
|
|
|
ExFreePool (DestinationString->Buffer);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
DestinationString->Buffer[Size] = 0;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
1999-11-20 21:49:23 +00:00
|
|
|
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlUnicodeStringToInteger (
|
|
|
|
IN PUNICODE_STRING String,
|
|
|
|
IN ULONG Base,
|
|
|
|
OUT PULONG Value
|
|
|
|
)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
2000-01-11 01:16:50 +00:00
|
|
|
PWCHAR Str;
|
|
|
|
ULONG lenmin = 0;
|
|
|
|
ULONG i;
|
|
|
|
ULONG Val;
|
|
|
|
BOOLEAN addneg = FALSE;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
2001-02-25 12:51:43 +00:00
|
|
|
*Value = 0;
|
2000-01-11 01:16:50 +00:00
|
|
|
Str = String->Buffer;
|
2001-02-25 12:51:43 +00:00
|
|
|
|
|
|
|
for (i = 0; i < String->Length / sizeof(WCHAR); i++)
|
2000-01-11 01:16:50 +00:00
|
|
|
{
|
|
|
|
if (*Str == L'b')
|
|
|
|
{
|
|
|
|
Base = 2;
|
|
|
|
lenmin++;
|
|
|
|
}
|
|
|
|
else if (*Str == L'o')
|
|
|
|
{
|
|
|
|
Base = 8;
|
|
|
|
lenmin++;
|
|
|
|
}
|
|
|
|
else if (*Str == L'd')
|
|
|
|
{
|
|
|
|
Base = 10;
|
|
|
|
lenmin++;
|
|
|
|
}
|
|
|
|
else if (*Str == L'x')
|
|
|
|
{
|
|
|
|
Base = 16;
|
|
|
|
lenmin++;
|
|
|
|
}
|
|
|
|
else if (*Str == L'+')
|
|
|
|
{
|
|
|
|
lenmin++;
|
|
|
|
}
|
|
|
|
else if (*Str == L'-')
|
|
|
|
{
|
|
|
|
addneg = TRUE;
|
|
|
|
lenmin++;
|
|
|
|
}
|
|
|
|
else if ((*Str > L'1') && (Base == 2))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
else if (((*Str > L'7') || (*Str < L'0')) && (Base == 8))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
else if (((*Str > L'9') || (*Str < L'0')) && (Base == 10))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
else if ((((*Str > L'9') || (*Str < L'0')) ||
|
|
|
|
((towupper (*Str) > L'F') ||
|
|
|
|
(towupper (*Str) < L'A'))) && (Base == 16))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
Str++;
|
|
|
|
}
|
|
|
|
|
|
|
|
Str = String->Buffer + lenmin;
|
|
|
|
|
|
|
|
if (Base == 0)
|
|
|
|
Base = 10;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
2000-01-11 01:16:50 +00:00
|
|
|
while (iswxdigit (*Str) &&
|
|
|
|
(Val = iswdigit (*Str) ? *Str - L'0' : (iswlower (*Str)
|
|
|
|
? toupper (*Str) : *Str) - L'A' + 10) < Base)
|
1999-11-20 21:49:23 +00:00
|
|
|
{
|
2000-01-11 01:16:50 +00:00
|
|
|
*Value = *Value * Base + Val;
|
|
|
|
Str++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (addneg == TRUE)
|
|
|
|
*Value *= -1;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
1999-03-25 00:37:06 +00:00
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
|
|
|
|
ULONG
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlUnicodeStringToOemSize (
|
|
|
|
IN PUNICODE_STRING UnicodeString
|
|
|
|
)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-15 16:02:50 +00:00
|
|
|
ULONG Size;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
RtlUnicodeToMultiByteSize (&Size,
|
|
|
|
UnicodeString->Buffer,
|
|
|
|
UnicodeString->Length);
|
|
|
|
|
|
|
|
return Size;
|
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlUnicodeStringToOemString (
|
|
|
|
IN OUT POEM_STRING DestinationString,
|
|
|
|
IN PUNICODE_STRING SourceString,
|
|
|
|
IN BOOLEAN AllocateDestinationString
|
|
|
|
)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG Length;
|
|
|
|
|
|
|
|
if (NlsMbOemCodePageTag == TRUE)
|
|
|
|
Length = RtlUnicodeStringToAnsiSize (SourceString);
|
|
|
|
else
|
|
|
|
Length = SourceString->Length / sizeof(WCHAR);
|
|
|
|
|
|
|
|
if (AllocateDestinationString == TRUE)
|
|
|
|
{
|
|
|
|
DestinationString->MaximumLength = Length + sizeof(CHAR);
|
|
|
|
DestinationString->Buffer =
|
|
|
|
ExAllocatePool (NonPagedPool,
|
|
|
|
DestinationString->MaximumLength);
|
|
|
|
if (DestinationString->Buffer == NULL)
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-12-10 17:49:21 +00:00
|
|
|
if (Length >= DestinationString->MaximumLength)
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
1999-12-10 17:49:21 +00:00
|
|
|
DestinationString->Length = Length;
|
1999-11-15 16:02:50 +00:00
|
|
|
|
|
|
|
RtlZeroMemory (DestinationString->Buffer,
|
|
|
|
DestinationString->Length);
|
|
|
|
|
|
|
|
Status = RtlUnicodeToOemN (DestinationString->Buffer,
|
|
|
|
DestinationString->Length,
|
|
|
|
NULL,
|
|
|
|
SourceString->Buffer,
|
|
|
|
SourceString->Length);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (AllocateDestinationString)
|
|
|
|
ExFreePool (DestinationString->Buffer);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
DestinationString->Buffer[Length] = 0;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
WCHAR
|
|
|
|
STDCALL
|
|
|
|
RtlUpcaseUnicodeChar (
|
|
|
|
WCHAR Source
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (Source < L'a')
|
|
|
|
return Source;
|
|
|
|
|
|
|
|
if (Source <= L'z')
|
|
|
|
return (Source - (L'a' - L'A'));
|
|
|
|
|
|
|
|
/* FIXME: characters above 'z' */
|
|
|
|
|
|
|
|
return Source;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlUpcaseUnicodeString (
|
|
|
|
IN OUT PUNICODE_STRING DestinationString,
|
|
|
|
IN PUNICODE_STRING SourceString,
|
|
|
|
IN BOOLEAN AllocateDestinationString
|
|
|
|
)
|
1999-11-15 16:02:50 +00:00
|
|
|
{
|
1999-11-20 21:49:23 +00:00
|
|
|
ULONG i;
|
|
|
|
PWCHAR Src, Dest;
|
1999-11-15 16:02:50 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
if (AllocateDestinationString == TRUE)
|
|
|
|
{
|
|
|
|
DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR);
|
|
|
|
DestinationString->Buffer = ExAllocatePool (NonPagedPool,
|
|
|
|
SourceString->Length + sizeof(WCHAR));
|
|
|
|
if (DestinationString->Buffer == NULL)
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (SourceString->Length >= DestinationString->MaximumLength)
|
1999-12-10 17:49:21 +00:00
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
1999-11-20 21:49:23 +00:00
|
|
|
}
|
1999-12-10 17:49:21 +00:00
|
|
|
DestinationString->Length = SourceString->Length;
|
1999-11-15 16:02:50 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
Src = SourceString->Buffer;
|
|
|
|
Dest = DestinationString->Buffer;
|
|
|
|
for (i=0; i < SourceString->Length / sizeof(WCHAR); i++)
|
|
|
|
{
|
|
|
|
*Dest = RtlUpcaseUnicodeChar (*Src);
|
|
|
|
Dest++;
|
|
|
|
Src++;
|
|
|
|
}
|
|
|
|
*Dest = 0;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
return STATUS_SUCCESS;
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
|
|
|
RtlUpcaseUnicodeStringToAnsiString (
|
|
|
|
IN OUT PANSI_STRING DestinationString,
|
|
|
|
IN PUNICODE_STRING SourceString,
|
|
|
|
IN BOOLEAN AllocateDestinationString
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG Length;
|
|
|
|
|
|
|
|
if (NlsMbCodePageTag == TRUE)
|
|
|
|
Length = RtlUnicodeStringToAnsiSize (SourceString);
|
|
|
|
else
|
|
|
|
Length = SourceString->Length / sizeof(WCHAR);
|
|
|
|
|
|
|
|
if (AllocateDestinationString == TRUE)
|
|
|
|
{
|
|
|
|
DestinationString->MaximumLength = Length + sizeof(CHAR);
|
|
|
|
DestinationString->Buffer = ExAllocatePool (NonPagedPool,
|
|
|
|
DestinationString->MaximumLength);
|
|
|
|
if (DestinationString->Buffer == NULL)
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-12-10 17:49:21 +00:00
|
|
|
if (Length >= DestinationString->MaximumLength)
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
1999-11-20 21:49:23 +00:00
|
|
|
}
|
1999-12-10 17:49:21 +00:00
|
|
|
DestinationString->Length = Length;
|
1999-11-20 21:49:23 +00:00
|
|
|
|
|
|
|
RtlZeroMemory (DestinationString->Buffer,
|
|
|
|
DestinationString->Length);
|
|
|
|
|
|
|
|
Status = RtlUpcaseUnicodeToMultiByteN (DestinationString->Buffer,
|
|
|
|
DestinationString->Length,
|
|
|
|
NULL,
|
|
|
|
SourceString->Buffer,
|
|
|
|
SourceString->Length);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (AllocateDestinationString)
|
|
|
|
ExFreePool (DestinationString->Buffer);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
DestinationString->Buffer[Length] = 0;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-03-03 00:48:50 +00:00
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
|
|
|
RtlUpcaseUnicodeStringToCountedOemString (
|
|
|
|
IN OUT POEM_STRING DestinationString,
|
|
|
|
IN PUNICODE_STRING SourceString,
|
|
|
|
IN BOOLEAN AllocateDestinationString
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG Length;
|
|
|
|
ULONG Size;
|
|
|
|
|
|
|
|
if (NlsMbCodePageTag == TRUE)
|
|
|
|
Length = RtlUnicodeStringToAnsiSize (SourceString) + 1;
|
|
|
|
else
|
|
|
|
Length = SourceString->Length / sizeof(WCHAR) + 1;
|
|
|
|
|
|
|
|
if (Length > 0x0000FFFF)
|
|
|
|
return STATUS_INVALID_PARAMETER_2;
|
|
|
|
|
|
|
|
DestinationString->Length = (WORD)(Length - 1);
|
|
|
|
|
|
|
|
if (AllocateDestinationString == TRUE)
|
|
|
|
{
|
|
|
|
DestinationString->Buffer = ExAllocatePool (NonPagedPool,
|
|
|
|
Length);
|
|
|
|
|
|
|
|
if (DestinationString->Buffer == NULL)
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
|
|
|
|
RtlZeroMemory (DestinationString->Buffer,
|
|
|
|
Length);
|
|
|
|
DestinationString->MaximumLength = (WORD)Length;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (Length > DestinationString->MaximumLength)
|
|
|
|
{
|
|
|
|
if (DestinationString->MaximumLength == 0)
|
|
|
|
return STATUS_BUFFER_OVERFLOW;
|
|
|
|
DestinationString->Length =
|
|
|
|
DestinationString->MaximumLength - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = RtlUpcaseUnicodeToOemN (DestinationString->Buffer,
|
|
|
|
DestinationString->Length,
|
|
|
|
&Size,
|
|
|
|
SourceString->Buffer,
|
|
|
|
SourceString->Length);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (AllocateDestinationString)
|
|
|
|
ExFreePool (DestinationString->Buffer);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
DestinationString->Buffer[Size] = 0;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
1999-11-20 21:49:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
|
|
|
RtlUpcaseUnicodeStringToOemString (
|
|
|
|
IN OUT POEM_STRING DestinationString,
|
|
|
|
IN PUNICODE_STRING SourceString,
|
|
|
|
IN BOOLEAN AllocateDestinationString
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG Length;
|
|
|
|
|
|
|
|
if (NlsMbOemCodePageTag == TRUE)
|
|
|
|
Length = RtlUnicodeStringToAnsiSize (SourceString);
|
|
|
|
else
|
|
|
|
Length = SourceString->Length / sizeof(WCHAR);
|
|
|
|
|
|
|
|
if (AllocateDestinationString == TRUE)
|
|
|
|
{
|
|
|
|
DestinationString->MaximumLength = Length + sizeof(CHAR);
|
|
|
|
DestinationString->Buffer = ExAllocatePool (NonPagedPool,
|
|
|
|
DestinationString->MaximumLength);
|
|
|
|
if (DestinationString->Buffer == NULL)
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-12-10 17:49:21 +00:00
|
|
|
if (Length >= DestinationString->MaximumLength)
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
1999-11-20 21:49:23 +00:00
|
|
|
}
|
1999-12-10 17:49:21 +00:00
|
|
|
DestinationString->Length = Length;
|
1999-11-20 21:49:23 +00:00
|
|
|
|
|
|
|
RtlZeroMemory (DestinationString->Buffer,
|
|
|
|
DestinationString->Length);
|
|
|
|
|
|
|
|
Status = RtlUpcaseUnicodeToOemN (DestinationString->Buffer,
|
|
|
|
DestinationString->Length,
|
|
|
|
NULL,
|
|
|
|
SourceString->Buffer,
|
|
|
|
SourceString->Length);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if (AllocateDestinationString)
|
|
|
|
ExFreePool (DestinationString->Buffer);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
DestinationString->Buffer[Length] = 0;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CHAR
|
1999-11-15 16:02:50 +00:00
|
|
|
STDCALL
|
1999-11-20 21:49:23 +00:00
|
|
|
RtlUpperChar (
|
|
|
|
IN CHAR Source
|
|
|
|
)
|
1999-01-16 21:03:00 +00:00
|
|
|
{
|
1999-11-20 21:49:23 +00:00
|
|
|
WCHAR Unicode;
|
|
|
|
CHAR Destination;
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
if (NlsMbCodePageTag == FALSE)
|
|
|
|
{
|
|
|
|
/* single-byte code page */
|
|
|
|
/* ansi->unicode */
|
|
|
|
Unicode = (WCHAR)Source;
|
|
|
|
#if 0
|
|
|
|
Unicode = NlsAnsiToUnicodeData[Source];
|
|
|
|
#endif
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
/* upcase conversion */
|
|
|
|
Unicode = RtlUpcaseUnicodeChar (Unicode);
|
1999-01-16 21:03:00 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
/* unicode -> ansi */
|
|
|
|
Destination = (CHAR)Unicode;
|
|
|
|
#if 0
|
|
|
|
Destination = NlsUnicodeToAnsiData[Unicode];
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* single-byte code page */
|
|
|
|
/* FIXME: implement the multi-byte stuff!! */
|
|
|
|
Destination = Source;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Destination;
|
1999-01-16 21:03:00 +00:00
|
|
|
}
|
1999-11-15 16:02:50 +00:00
|
|
|
|
1999-11-20 21:49:23 +00:00
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
VOID
|
|
|
|
STDCALL
|
|
|
|
RtlUpperString(PSTRING DestinationString, PSTRING SourceString)
|
|
|
|
{
|
1999-11-20 21:49:23 +00:00
|
|
|
ULONG Length;
|
|
|
|
ULONG i;
|
|
|
|
PCHAR Src;
|
|
|
|
PCHAR Dest;
|
|
|
|
|
|
|
|
Length = min(SourceString->Length, DestinationString->MaximumLength - 1);
|
|
|
|
|
|
|
|
Src = SourceString->Buffer;
|
|
|
|
Dest = DestinationString->Buffer;
|
|
|
|
for (i = 0; i < Length; i++)
|
|
|
|
{
|
|
|
|
*Dest = RtlUpperChar (*Src);
|
|
|
|
Src++;
|
|
|
|
Dest++;
|
|
|
|
}
|
|
|
|
*Dest = 0;
|
|
|
|
|
|
|
|
DestinationString->Length = SourceString->Length;
|
1999-11-15 16:02:50 +00:00
|
|
|
}
|
|
|
|
|
1999-11-25 23:35:24 +00:00
|
|
|
|
|
|
|
ULONG
|
|
|
|
STDCALL
|
|
|
|
RtlxAnsiStringToUnicodeSize (
|
|
|
|
IN PANSI_STRING AnsiString
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return RtlAnsiStringToUnicodeSize (AnsiString);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ULONG
|
|
|
|
STDCALL
|
|
|
|
RtlxOemStringToUnicodeSize (
|
|
|
|
IN POEM_STRING OemString
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return RtlAnsiStringToUnicodeSize ((PANSI_STRING)OemString);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ULONG
|
|
|
|
STDCALL
|
|
|
|
RtlxUnicodeStringToAnsiSize (
|
|
|
|
IN PUNICODE_STRING UnicodeString
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return RtlUnicodeStringToAnsiSize (UnicodeString);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ULONG
|
|
|
|
STDCALL
|
|
|
|
RtlxUnicodeStringToOemSize (
|
|
|
|
IN PUNICODE_STRING UnicodeString
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return RtlUnicodeStringToAnsiSize (UnicodeString);
|
|
|
|
}
|
|
|
|
|
1999-11-15 16:02:50 +00:00
|
|
|
/* EOF */
|