fixed returned status code in RtlAnsiStringToUnicodeString and properly free allocate...
[reactos.git] / reactos / lib / rtl / unicode.c
index 9905fc9..9b29db3 100644 (file)
 /*
- * Rtl string functions
- *
- * Copyright (C) 1996-1998 Marcus Meissner
- * Copyright (C) 2000      Alexandre Julliard
- * Copyright (C) 2003      Thomas Mertes
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * COPYRIGHT:         See COPYING in the top level directory
+ * PROJECT:           ReactOS system libraries
+ * PURPOSE:           Unicode Conversion Routines
+ * FILE:              lib/rtl/unicode.c
+ * PROGRAMMER:        Alex Ionescu (alex@relsoft.net)
+ *                    Emanuele Aliberti
+ *                    Gunnar Dalsnes
  */
 
+/* INCLUDES *****************************************************************/
 
-#define __NTDRIVER__
-#include <ddk/ntddk.h>
-
-#include <ntdll/rtl.h>
-
-#include <ntos/minmax.h>
-#define __NO_CTYPE_INLINES
-#include <ctype.h>
+#include <rtl.h>
 
 #define NDEBUG
 #include <debug.h>
 
 /* GLOBALS *******************************************************************/
 
-#define TAG_USTR  TAG('U', 'S', 'T', 'R')
-#define TAG_ASTR  TAG('A', 'S', 'T', 'R')
-#define TAG_OSTR  TAG('O', 'S', 'T', 'R')
-
-
 extern BOOLEAN NlsMbCodePageTag;
 extern BOOLEAN NlsMbOemCodePageTag;
+extern PUSHORT NlsLeadByteInfo;
 
 /* FUNCTIONS *****************************************************************/
 
-
 /*
 * @implemented
 */
-WCHAR STDCALL
-RtlAnsiCharToUnicodeChar (IN CHAR AnsiChar)
+WCHAR
+NTAPI
+RtlAnsiCharToUnicodeChar(IN PUCHAR *AnsiChar)
 {
-   ULONG Size;
-   WCHAR UnicodeChar;
+    ULONG Size;
+    NTSTATUS Status;
+    WCHAR UnicodeChar = L' ';
 
-   Size = 1;
-#if 0
+    Size = (NlsLeadByteInfo[**AnsiChar] == 0) ? 1 : 2;
 
-   Size = (NlsLeadByteInfo[AnsiChar] == 0) ? 1 : 2;
-#endif
+    Status = RtlMultiByteToUnicodeN(&UnicodeChar,
+                                    sizeof(WCHAR),
+                                    NULL,
+                                    (PCHAR)*AnsiChar,
+                                    Size);
 
-   RtlMultiByteToUnicodeN (&UnicodeChar,
-                           sizeof(WCHAR),
-                           NULL,
-                           &AnsiChar,
-                           Size);
+    if (!NT_SUCCESS(Status))
+    {
+        UnicodeChar = L' ';
+    }
 
-   return UnicodeChar;
+    *AnsiChar += Size;
+    return UnicodeChar;
 }
 
+/*
+ * @implemented
+ *
+ * NOTES
+ *  This function always writes a terminating '\0'.
+ *  If the dest buffer is too small a partial copy is NOT performed!
+ */
+NTSTATUS
+NTAPI
+RtlAnsiStringToUnicodeString(
+   IN OUT PUNICODE_STRING UniDest,
+   IN PANSI_STRING AnsiSource,
+   IN BOOLEAN AllocateDestinationString)
+{
+    NTSTATUS Status;
+    ULONG Length;
+    ULONG Index;
+
+    PAGED_CODE_RTL();
+
+    Length = RtlAnsiStringToUnicodeSize(AnsiSource);
+    if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
+    UniDest->Length = (USHORT)Length - sizeof(WCHAR);
+
+    if (AllocateDestinationString)
+    {
+        UniDest->Buffer = RtlpAllocateStringMemory(Length, TAG_USTR);
+        UniDest->MaximumLength = Length;
+        if (!UniDest->Buffer) return STATUS_NO_MEMORY;
+    }
+    else if (UniDest->Length >= UniDest->MaximumLength)
+    {
+        return STATUS_BUFFER_OVERFLOW;
+    }
+
+    Status = RtlMultiByteToUnicodeN(UniDest->Buffer,
+                                    UniDest->Length,
+                                    &Index,
+                                    AnsiSource->Buffer,
+                                    AnsiSource->Length);
+
+    if (!NT_SUCCESS(Status))
+    {
+        if (AllocateDestinationString)
+        {
+            RtlpFreeStringMemory(UniDest->Buffer, TAG_USTR);
+            UniDest->Buffer = NULL;
+        }
+        return Status;
+    }
+
+    UniDest->Buffer[Index / sizeof(WCHAR)] = UNICODE_NULL;
+    return Status;
+}
 
 /*
  * @implemented
@@ -78,20 +113,20 @@ RtlAnsiCharToUnicodeChar (IN CHAR AnsiChar)
  *  The calculated size in bytes including nullterm.
  */
 ULONG
-STDCALL
-RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
+NTAPI
+RtlxAnsiStringToUnicodeSize(IN PCANSI_STRING AnsiString)
 {
-   ULONG Size;
+    ULONG Size;
 
-   RtlMultiByteToUnicodeSize(&Size,
-                             AnsiString->Buffer,
-                             AnsiString->Length);
+    /* Convert from Mb String to Unicode Size */
+    RtlMultiByteToUnicodeSize(&Size,
+                              AnsiString->Buffer,
+                              AnsiString->Length);
 
-   return(Size);
+    /* Return the size plus the null-char */
+    return(Size + sizeof(WCHAR));
 }
 
-
-
 /*
  * @implemented
  *
@@ -100,32 +135,29 @@ RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
  *  Dest is never nullterminated.
  */
 NTSTATUS
-STDCALL
-RtlAppendStringToString(IN OUT PSTRING Destination,
+NTAPI
+RtlAppendStringToString(IN PSTRING Destination,
                         IN PSTRING Source)
 {
-   PCHAR Ptr;
-
-   if (Source->Length == 0)
-      return(STATUS_SUCCESS);
+    USHORT SourceLength = Source->Length;
 
-   if (Destination->Length + Source->Length >= Destination->MaximumLength)
-      return(STATUS_BUFFER_TOO_SMALL);
+    if (SourceLength)
+    {
+        if (Destination->Length + SourceLength > Destination->MaximumLength)
+        {
+            return STATUS_BUFFER_TOO_SMALL;
+        }
 
-   Ptr = Destination->Buffer + Destination->Length;
-   memmove(Ptr,
-           Source->Buffer,
-           Source->Length);
-   Ptr += Source->Length;
-   *Ptr = 0;
+        RtlMoveMemory(&Destination->Buffer[Destination->Length],
+                      Source->Buffer,
+                      SourceLength);
 
-   Destination->Length += Source->Length;
+        Destination->Length += SourceLength;
+    }
 
-   return(STATUS_SUCCESS);
+    return STATUS_SUCCESS;
 }
 
-
-
 /*
  * @implemented
  *
@@ -135,120 +167,154 @@ RtlAppendStringToString(IN OUT PSTRING Destination,
  *  When dest fits exactly in MaximumLength characters the nullterm is ommitted.
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlAppendUnicodeStringToString(
    IN OUT PUNICODE_STRING Destination,
-   IN PUNICODE_STRING Source)
+   IN PCUNICODE_STRING Source)
 {
+    USHORT SourceLength = Source->Length;
+    PWCHAR Buffer = &Destination->Buffer[Destination->Length / sizeof(WCHAR)];
 
-   if ((Source->Length + Destination->Length) > Destination->MaximumLength)
-      return STATUS_BUFFER_TOO_SMALL;
+    if (SourceLength)
+    {
+        if ((SourceLength+ Destination->Length) > Destination->MaximumLength)
+        {
+            return STATUS_BUFFER_TOO_SMALL;
+        }
 
-   memcpy((char*)Destination->Buffer + Destination->Length, Source->Buffer, Source->Length);
-   Destination->Length += Source->Length;
-   /* append terminating '\0' if enough space */
-   if( Destination->MaximumLength > Destination->Length )
-      Destination->Buffer[Destination->Length / sizeof(WCHAR)] = 0;
+        RtlMoveMemory(Buffer, Source->Buffer, SourceLength);
+        Destination->Length += SourceLength;
 
-   return STATUS_SUCCESS;
-}
+        /* append terminating '\0' if enough space */
+        if (Destination->MaximumLength > Destination->Length)
+        {
+            Buffer[SourceLength / sizeof(WCHAR)] = UNICODE_NULL;
+        }
+    }
 
+    return STATUS_SUCCESS;
+}
 
-/*
+/**************************************************************************
+ *      RtlCharToInteger   (NTDLL.@)
  * @implemented
+ * Converts a character string into its integer equivalent.
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS. value contains the converted number
+ *  Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
+ *           STATUS_ACCESS_VIOLATION, if value is NULL.
+ *
+ * NOTES
+ *  For base 0 it uses 10 as base and the string should be in the format
+ *      "{whitespace} [+|-] [0[x|o|b]] {digits}".
+ *  For other bases the string should be in the format
+ *      "{whitespace} [+|-] {digits}".
+ *  No check is made for value overflow, only the lower 32 bits are assigned.
+ *  If str is NULL it crashes, as the native function does.
+ *
+ * DIFFERENCES
+ *  This function does not read garbage behind '\0' as the native version does.
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlCharToInteger(
-   IN PCSZ String,
-   IN ULONG Base,
-   IN OUT PULONG Value)
-{
-   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++;
-   }
-
-   return STATUS_SUCCESS;
+    PCSZ str,      /* [I] '\0' terminated single-byte string containing a number */
+    ULONG base,    /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
+    PULONG value)  /* [O] Destination for the converted value */
+{
+    CHAR chCurrent;
+    int digit;
+    ULONG RunningTotal = 0;
+    char bMinus = 0;
+
+    while (*str != '\0' && *str <= ' ') {
+       str++;
+    } /* while */
+
+    if (*str == '+') {
+       str++;
+    } else if (*str == '-') {
+       bMinus = 1;
+       str++;
+    } /* if */
+
+    if (base == 0) {
+       base = 10;
+       if (str[0] == '0') {
+           if (str[1] == 'b') {
+               str += 2;
+               base = 2;
+           } else if (str[1] == 'o') {
+               str += 2;
+               base = 8;
+           } else if (str[1] == 'x') {
+               str += 2;
+               base = 16;
+           } /* if */
+       } /* if */
+    } else if (base != 2 && base != 8 && base != 10 && base != 16) {
+       return STATUS_INVALID_PARAMETER;
+    } /* if */
+
+    if (value == NULL) {
+       return STATUS_ACCESS_VIOLATION;
+    } /* if */
+
+    while (*str != '\0') {
+       chCurrent = *str;
+       if (chCurrent >= '0' && chCurrent <= '9') {
+           digit = chCurrent - '0';
+       } else if (chCurrent >= 'A' && chCurrent <= 'Z') {
+           digit = chCurrent - 'A' + 10;
+       } else if (chCurrent >= 'a' && chCurrent <= 'z') {
+           digit = chCurrent - 'a' + 10;
+       } else {
+           digit = -1;
+       } /* if */
+       if (digit < 0 || digit >= (int)base) {
+           *value = bMinus ? -RunningTotal : RunningTotal;
+           return STATUS_SUCCESS;
+       } /* if */
+
+       RunningTotal = RunningTotal * base + digit;
+       str++;
+    } /* while */
+
+    *value = bMinus ? -RunningTotal : RunningTotal;
+    return STATUS_SUCCESS;
 }
 
-
-
 /*
  * @implemented
  */
 LONG
-STDCALL
+NTAPI
 RtlCompareString(
-   IN PSTRING String1,
-   IN PSTRING String2,
+   IN PSTRING s1,
+   IN PSTRING s2,
    IN BOOLEAN CaseInsensitive)
 {
-   ULONG len1, len2;
-   PCHAR s1, s2;
-   CHAR  c1, c2;
+   unsigned int len;
+   LONG ret = 0;
+   LPCSTR p1, p2;
 
-   if (String1 && String2)
-   {
-      len1 = String1->Length;
-      len2 = String2->Length;
-      s1 = String1->Buffer;
-      s2 = String2->Buffer;
+   len = min(s1->Length, s2->Length);
+   p1 = s1->Buffer;
+   p2 = s2->Buffer;
 
-      if (s1 && s2)
-      {
-         if (CaseInsensitive)
-         {
-            for(;;)
-            {
-               c1 = len1-- ? RtlUpperChar (*s1++) : 0;
-               c2 = len2-- ? RtlUpperChar (*s2++) : 0;
-               if (!c1 || !c2 || c1 != c2)
-                  return c1 - c2;
-            }
-         }
-         else
-         {
-            for(;;)
-            {
-               c1 = len1-- ? *s1++ : 0;
-               c2 = len2-- ? *s2++ : 0;
-               if (!c1 || !c2 || c1 != c2)
-                  return c1 - c2;
-            }
-         }
-      }
+   if (CaseInsensitive)
+   {
+     while (!ret && len--) ret = RtlUpperChar(*p1++) - RtlUpperChar(*p2++);
    }
-
-   return 0;
+   else
+   {
+     while (!ret && len--) ret = *p1++ - *p2++;
+   }
+   if (!ret) ret = s1->Length - s2->Length;
+   return ret;
 }
 
-
 /*
  * @implemented
  *
@@ -256,45 +322,16 @@ RtlCompareString(
  *  TRUE if strings are equal.
  */
 BOOLEAN
-STDCALL
+NTAPI
 RtlEqualString(
-   IN PSTRING String1,
-   IN PSTRING String2,
+   IN PSTRING s1,
+   IN PSTRING s2,
    IN BOOLEAN CaseInsensitive)
 {
-   ULONG i;
-   CHAR c1, c2;
-   PCHAR p1, p2;
-
-   if (String1->Length != String2->Length)
-      return FALSE;
-
-   p1 = String1->Buffer;
-   p2 = String2->Buffer;
-   for (i = 0; i < String1->Length; i++)
-   {
-      if (CaseInsensitive == TRUE)
-      {
-         c1 = RtlUpperChar (*p1);
-         c2 = RtlUpperChar (*p2);
-      }
-      else
-      {
-         c1 = *p1;
-         c2 = *p2;
-      }
-
-      if (c1 != c2)
-         return FALSE;
-
-      p1++;
-      p2++;
-   }
-
-   return TRUE;
+    if (s1->Length != s2->Length) return FALSE;
+    return !RtlCompareString(s1, s2, CaseInsensitive);
 }
 
-
 /*
  * @implemented
  *
@@ -302,110 +339,69 @@ RtlEqualString(
  *  TRUE if strings are equal.
  */
 BOOLEAN
-STDCALL
+NTAPI
 RtlEqualUnicodeString(
-   IN PUNICODE_STRING String1,
-   IN PUNICODE_STRING String2,
+   IN CONST UNICODE_STRING *s1,
+   IN CONST UNICODE_STRING *s2,
    IN BOOLEAN  CaseInsensitive)
 {
-   ULONG i;
-   WCHAR wc1, wc2;
-   PWCHAR pw1, pw2;
-
-   if (String1->Length != String2->Length)
-      return FALSE;
-
-   pw1 = String1->Buffer;
-   pw2 = String2->Buffer;
-
-   for (i = 0; i < String1->Length / sizeof(WCHAR); i++)
-   {
-      if (CaseInsensitive == TRUE)
-      {
-         wc1 = RtlUpcaseUnicodeChar (*pw1);
-         wc2 = RtlUpcaseUnicodeChar (*pw2);
-      }
-      else
-      {
-         wc1 = *pw1;
-         wc2 = *pw2;
-      }
-
-      if (wc1 != wc2)
-         return FALSE;
-
-      pw1++;
-      pw2++;
-   }
-
-   return TRUE;
+    if (s1->Length != s2->Length) return FALSE;
+    return !RtlCompareUnicodeString(s1, s2, CaseInsensitive );
 }
 
-
 /*
  * @implemented
  */
 VOID
-STDCALL
+NTAPI
 RtlFreeAnsiString(IN PANSI_STRING AnsiString)
 {
-   if (AnsiString->Buffer == NULL)
-      return;
-
-   ExFreePool(AnsiString->Buffer);
+    PAGED_CODE_RTL();
 
-   AnsiString->Buffer = NULL;
-   AnsiString->Length = 0;
-   AnsiString->MaximumLength = 0;
+    if (AnsiString->Buffer)
+    {
+        RtlpFreeStringMemory(AnsiString->Buffer, TAG_ASTR);
+        RtlZeroMemory(AnsiString, sizeof(ANSI_STRING));
+    }
 }
 
-
 /*
  * @implemented
  */
 VOID
-STDCALL
+NTAPI
 RtlFreeOemString(IN POEM_STRING OemString)
 {
-   if (OemString->Buffer == NULL)
-      return;
-
-   ExFreePool(OemString->Buffer);
+   PAGED_CODE_RTL();
 
-   OemString->Buffer = NULL;
-   OemString->Length = 0;
-   OemString->MaximumLength = 0;
+   if (OemString->Buffer) RtlpFreeStringMemory(OemString->Buffer, TAG_OSTR);
 }
 
-
 /*
  * @implemented
  */
 VOID
-STDCALL
+NTAPI
 RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
 {
-   if (UnicodeString->Buffer == NULL)
-      return;
-
-   ExFreePool(UnicodeString->Buffer);
+    PAGED_CODE_RTL();
 
-   UnicodeString->Buffer = NULL;
-   UnicodeString->Length = 0;
-   UnicodeString->MaximumLength = 0;
+    if (UnicodeString->Buffer)
+    {
+        RtlpFreeStringMemory(UnicodeString->Buffer, TAG_ASTR);
+        RtlZeroMemory(UnicodeString, sizeof(UNICODE_STRING));
+    }
 }
 
 /*
 * @unimplemented
 */
 BOOLEAN
-STDCALL
-RtlIsValidOemCharacter (
-       IN PWCHAR Char
-       )
+NTAPI
+RtlIsValidOemCharacter(IN PWCHAR Char)
 {
-       UNIMPLEMENTED;
-       return FALSE;
+    UNIMPLEMENTED;
+    return FALSE;
 }
 
 /*
@@ -415,27 +411,26 @@ RtlIsValidOemCharacter (
  *  If source is NULL the length of source is assumed to be 0.
  */
 VOID
-STDCALL
+NTAPI
 RtlInitAnsiString(IN OUT PANSI_STRING DestinationString,
                   IN PCSZ SourceString)
 {
-   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;
-}
+    ULONG DestSize;
 
+    if(SourceString)
+    {
+        DestSize = strlen(SourceString);
+        DestinationString->Length = (USHORT)DestSize;
+        DestinationString->MaximumLength = (USHORT)DestSize + sizeof(CHAR);
+    }
+    else
+    {
+        DestinationString->Length = 0;
+        DestinationString->MaximumLength = 0;
+    }
 
+    DestinationString->Buffer = (PCHAR)SourceString;
+}
 
 /*
  * @implemented
@@ -444,28 +439,14 @@ RtlInitAnsiString(IN OUT PANSI_STRING DestinationString,
  *  If source is NULL the length of source is assumed to be 0.
  */
 VOID
-STDCALL
+NTAPI
 RtlInitString(
    IN OUT PSTRING DestinationString,
    IN PCSZ SourceString)
 {
-   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;
+    RtlInitAnsiString(DestinationString, SourceString);
 }
 
-
 /*
  * @implemented
  *
@@ -473,57 +454,52 @@ RtlInitString(
  *  If source is NULL the length of source is assumed to be 0.
  */
 VOID
-STDCALL
+NTAPI
 RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,
                      IN PCWSTR SourceString)
 {
-   ULONG DestSize;
+    ULONG DestSize;
 
-   DPRINT("RtlInitUnicodeString(DestinationString %x, SourceString %x)\n",
-          DestinationString,
-          SourceString);
+    if(SourceString)
+    {
+        DestSize = wcslen(SourceString) * sizeof(WCHAR);
+        DestinationString->Length = (USHORT)DestSize;
+        DestinationString->MaximumLength = (USHORT)DestSize + sizeof(WCHAR);
+    }
+    else
+    {
+        DestinationString->Length = 0;
+        DestinationString->MaximumLength = 0;
+    }
 
-   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;
+    DestinationString->Buffer = (PWCHAR)SourceString;
 }
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS
+NTAPI
 RtlInitUnicodeStringEx(OUT PUNICODE_STRING DestinationString,
                        IN PCWSTR SourceString)
 {
-   ULONG Length;
-
-   if (SourceString != NULL)
-   {
-      Length = wcslen(SourceString) * sizeof(WCHAR);
-      if (Length > 0xFFFC)
-         return STATUS_NAME_TOO_LONG;
+    ULONG DestSize;
 
-      DestinationString->Length = Length;
-      DestinationString->MaximumLength = Length + sizeof(WCHAR);
-      DestinationString->Buffer = (PWSTR)SourceString;
-   }
-   else
-   {
-      DestinationString->Length = 0;
-      DestinationString->MaximumLength = 0;
-      DestinationString->Buffer = NULL;
-   }
+    if(SourceString)
+    {
+        DestSize = wcslen(SourceString) * sizeof(WCHAR);
+        if (DestSize >= 0xFFFC) return STATUS_NAME_TOO_LONG;
+        DestinationString->Length = (USHORT)DestSize;
+        DestinationString->MaximumLength = (USHORT)DestSize + sizeof(WCHAR);
+    }
+    else
+    {
+        DestinationString->Length = 0;
+        DestinationString->MaximumLength = 0;
+    }
 
-   return STATUS_SUCCESS;
+    DestinationString->Buffer = (PWCHAR)SourceString;
+    return STATUS_SUCCESS;
 }
 
 /*
@@ -535,7 +511,7 @@ RtlInitUnicodeStringEx(OUT PUNICODE_STRING DestinationString,
  *  When str fits exactly in length characters the nullterm is ommitted.
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlIntegerToChar(
    IN ULONG Value,
    IN ULONG Base,
@@ -571,7 +547,7 @@ RtlIntegerToChar(
       tp++;
    }
 
-   if (tp - temp >= Length)
+   if ((ULONG)((ULONG_PTR)tp - (ULONG_PTR)temp) >= Length)
    {
       return STATUS_BUFFER_TOO_SMALL;
    }
@@ -584,12 +560,11 @@ RtlIntegerToChar(
    return STATUS_SUCCESS;
 }
 
-
 /*
  * @implemented
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlIntegerToUnicode(
     IN ULONG Value,
     IN ULONG Base  OPTIONAL,
@@ -626,7 +601,7 @@ RtlIntegerToUnicode(
       tp++;
    }
 
-   if (tp - temp >= Length)
+   if ((ULONG)((ULONG_PTR)tp - (ULONG_PTR)temp) >= Length)
    {
       return STATUS_BUFFER_TOO_SMALL;
    }
@@ -639,77 +614,62 @@ RtlIntegerToUnicode(
    return STATUS_SUCCESS;
 }
 
-
-
 /*
  * @implemented
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlIntegerToUnicodeString(
-   IN ULONG  Value,
-   IN ULONG  Base, /* optional */
+   IN ULONG Value,
+   IN ULONG Base OPTIONAL,
    IN OUT PUNICODE_STRING String)
 {
-   ANSI_STRING AnsiString;
-   CHAR Buffer[33];
-   NTSTATUS Status;
-
-   Status = RtlIntegerToChar (Value,
-                              Base,
-                              sizeof(Buffer),
-                              Buffer);
-   if (!NT_SUCCESS(Status))
-      return Status;
-
-   AnsiString.Buffer = Buffer;
-   AnsiString.Length = strlen (Buffer);
-   AnsiString.MaximumLength = sizeof(Buffer);
-
-   Status = RtlAnsiStringToUnicodeString (String,
-                                          &AnsiString,
-                                          FALSE);
+    ANSI_STRING AnsiString;
+    CHAR Buffer[16];
+    NTSTATUS Status;
 
-   return Status;
-}
+    Status = RtlIntegerToChar(Value, Base, sizeof(Buffer), Buffer);
+    if (NT_SUCCESS(Status))
+    {
+        AnsiString.Buffer = Buffer;
+        AnsiString.Length = (USHORT)strlen(Buffer);
+        AnsiString.MaximumLength = sizeof(Buffer);
 
+        Status = RtlAnsiStringToUnicodeString(String, &AnsiString, FALSE);
+    }
+
+    return Status;
+}
 
 /*
-* @implemented
-*/
+ * @implemented
+ */
 NTSTATUS
-STDCALL
+NTAPI
 RtlInt64ToUnicodeString (
-       IN ULONGLONG Value,
-       IN ULONG Base OPTIONAL,
-       IN OUT PUNICODE_STRING String
-       )
+    IN ULONGLONG Value,
+    IN ULONG Base OPTIONAL,
+    IN OUT PUNICODE_STRING String)
 {
-   LARGE_INTEGER LargeInt;
-   ANSI_STRING AnsiString;
-   CHAR Buffer[33];
-   NTSTATUS Status;
-   
-   LargeInt.QuadPart = Value;
-
-   Status = RtlLargeIntegerToChar (&LargeInt,
-                                   Base,
-                                   sizeof(Buffer),
-                                   Buffer);
-   if (!NT_SUCCESS(Status))
-      return Status;
-
-   AnsiString.Buffer = Buffer;
-   AnsiString.Length = strlen (Buffer);
-   AnsiString.MaximumLength = sizeof(Buffer);
-
-   Status = RtlAnsiStringToUnicodeString (String,
-                                          &AnsiString,
-                                          FALSE);
+    LARGE_INTEGER LargeInt;
+    ANSI_STRING AnsiString;
+    CHAR Buffer[32];
+    NTSTATUS Status;
 
-   return Status;
-}
+    LargeInt.QuadPart = Value;
+
+    Status = RtlLargeIntegerToChar(&LargeInt, Base, sizeof(Buffer), Buffer);
+    if (NT_SUCCESS(Status))
+    {
+        AnsiString.Buffer = Buffer;
+        AnsiString.Length = (USHORT)strlen(Buffer);
+        AnsiString.MaximumLength = sizeof(Buffer);
+
+        Status = RtlAnsiStringToUnicodeString(String, &AnsiString, FALSE);
+    }
 
+    return Status;
+}
 
 /*
  * @implemented
@@ -718,7 +678,7 @@ RtlInt64ToUnicodeString (
  *  TRUE if String2 contains String1 as a prefix.
  */
 BOOLEAN
-STDCALL
+NTAPI
 RtlPrefixString(
    PANSI_STRING String1,
    PANSI_STRING String2,
@@ -758,7 +718,6 @@ RtlPrefixString(
    return FALSE;
 }
 
-
 /*
  * @implemented
  *
@@ -766,10 +725,10 @@ RtlPrefixString(
  *  TRUE if String2 contains String1 as a prefix.
  */
 BOOLEAN
-STDCALL
+NTAPI
 RtlPrefixUnicodeString(
-   PUNICODE_STRING String1,
-   PUNICODE_STRING String2,
+   PCUNICODE_STRING String1,
+   PCUNICODE_STRING String2,
    BOOLEAN  CaseInsensitive)
 {
    PWCHAR pc1;
@@ -807,113 +766,117 @@ RtlPrefixUnicodeString(
    return FALSE;
 }
 
-
-
-/*
+/**************************************************************************
+ *      RtlUnicodeStringToInteger (NTDLL.@)
  * @implemented
+ * Converts an unicode string into its integer equivalent.
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS. value contains the converted number
+ *  Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
+ *           STATUS_ACCESS_VIOLATION, if value is NULL.
+ *
+ * NOTES
+ *  For base 0 it uses 10 as base and the string should be in the format
+ *      "{whitespace} [+|-] [0[x|o|b]] {digits}".
+ *  For other bases the string should be in the format
+ *      "{whitespace} [+|-] {digits}".
+ *  No check is made for value overflow, only the lower 32 bits are assigned.
+ *  If str is NULL it crashes, as the native function does.
  *
- * Note that regardless of success or failure status, we should leave the
- * partial value in Value.  An error is never returned based on the chars
- * in the string.
+ *  Note that regardless of success or failure status, we should leave the
+ *  partial value in Value.  An error is never returned based on the chars
+ *  in the string.
  *
- * This function does check the base.  Only 2, 8, 10, 16 are permitted,
- * else STATUS_INVALID_PARAMETER is returned.
+ * DIFFERENCES
+ *  This function does not read garbage on string length 0 as the native
+ *  version does.
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlUnicodeStringToInteger(
-   IN PUNICODE_STRING String,
-   IN ULONG  Base,
-   OUT PULONG  Value)
-{
-   PWCHAR Str;
-   ULONG lenmin = 0;
-   ULONG i;
-   ULONG Val;
-   BOOLEAN addneg = FALSE;
-   NTSTATUS Status = STATUS_SUCCESS;
-
-   *Value = 0;
-   Str = String->Buffer;
-
-   if( Base && Base != 2 && Base != 8 && Base != 10 && Base != 16 )
-       return STATUS_INVALID_PARAMETER;
-
-   for (i = 0; i < String->Length / sizeof(WCHAR); i++)
-   {
-      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))
-      {
-         break;
-      }
-      else if (((*Str > L'7') || (*Str < L'0')) && (Base == 8))
-      {
-         break;
-      }
-      else if (((*Str > L'9') || (*Str < L'0')) && (Base == 10))
-      {
-         break;
-      }
-      else if (  ((*Str > L'9') || (*Str < L'0')) &&
-                 ((towupper (*Str) > L'F') || (towupper (*Str) < L'A')) &&
-                 (Base == 16))
-      {
-         break;
-      }
-      Str++;
-   }
-
-   Str = String->Buffer + lenmin;
-
-   if (Base == 0)
-      Base = 10;
-
-   while (iswxdigit (*Str) &&
-          (Val = 
-          iswdigit (*Str) ? 
-          *Str - L'0' : 
-          (towupper (*Str) - L'A' + 10)) < Base)
-   {
-      *Value = *Value * Base + Val;
-      Str++;
-   }
-
-   if (addneg == TRUE)
-      *Value *= -1;
-
-   return Status;
+    PCUNICODE_STRING str, /* [I] Unicode string to be converted */
+    ULONG base,                /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
+    PULONG value)              /* [O] Destination for the converted value */
+{
+    LPWSTR lpwstr = str->Buffer;
+    USHORT CharsRemaining = str->Length / sizeof(WCHAR);
+    WCHAR wchCurrent;
+    int digit;
+    ULONG newbase = 0;
+    ULONG RunningTotal = 0;
+    char bMinus = 0;
+
+    while (CharsRemaining >= 1 && *lpwstr <= L' ') {
+       lpwstr++;
+       CharsRemaining--;
+    } /* while */
+
+    if (CharsRemaining >= 1) {
+       if (*lpwstr == L'+') {
+           lpwstr++;
+           CharsRemaining--;
+       } else if (*lpwstr == L'-') {
+           bMinus = 1;
+           lpwstr++;
+           CharsRemaining--;
+       } /* if */
+    } /* if */
+
+    if (CharsRemaining >= 2 && lpwstr[0] == L'0') {
+        if (lpwstr[1] == L'b' || lpwstr[1] == L'B') {
+           lpwstr += 2;
+           CharsRemaining -= 2;
+           newbase = 2;
+       } else if (lpwstr[1] == L'o' || lpwstr[1] == L'O') {
+           lpwstr += 2;
+           CharsRemaining -= 2;
+           newbase = 8;
+        } else if (lpwstr[1] == L'x' || lpwstr[1] == L'X') {
+           lpwstr += 2;
+           CharsRemaining -= 2;
+           newbase = 16;
+       } /* if */
+    }
+    if (base == 0 && newbase == 0) {
+        base = 10;
+    } else if (base == 0 && newbase != 0) {
+        base = newbase;
+    } else if ((newbase != 0 && base != newbase) ||
+               (base != 2 && base != 8 && base != 10 && base != 16)) {
+       return STATUS_INVALID_PARAMETER;
+
+    } /* if */
+
+    if (value == NULL) {
+       return STATUS_ACCESS_VIOLATION;
+    } /* if */
+
+    while (CharsRemaining >= 1) {
+       wchCurrent = *lpwstr;
+       if (wchCurrent >= L'0' && wchCurrent <= L'9') {
+           digit = wchCurrent - L'0';
+       } else if (wchCurrent >= L'A' && wchCurrent <= L'Z') {
+           digit = wchCurrent - L'A' + 10;
+       } else if (wchCurrent >= L'a' && wchCurrent <= L'z') {
+           digit = wchCurrent - L'a' + 10;
+       } else {
+           digit = -1;
+       } /* if */
+       if (digit < 0 || digit >= (int)base) {
+           *value = bMinus ? -RunningTotal : RunningTotal;
+           return STATUS_SUCCESS;
+       } /* if */
+
+       RunningTotal = RunningTotal * base + digit;
+       lpwstr++;
+       CharsRemaining--;
+    } /* while */
+
+    *value = bMinus ? -RunningTotal : RunningTotal;
+    return STATUS_SUCCESS;
 }
 
-
-
 /*
  * @implemented
  *
@@ -921,283 +884,190 @@ RtlUnicodeStringToInteger(
  *  Bytes necessary for the conversion including nullterm.
  */
 ULONG
-STDCALL
-RtlUnicodeStringToOemSize(
-   IN PUNICODE_STRING UnicodeString)
+NTAPI
+RtlxUnicodeStringToOemSize(IN PCUNICODE_STRING UnicodeString)
 {
-   ULONG Size;
+    ULONG Size;
 
-   RtlUnicodeToMultiByteSize (&Size,
+    /* Convert the Unicode String to Mb Size */
+    RtlUnicodeToMultiByteSize(&Size,
                               UnicodeString->Buffer,
                               UnicodeString->Length);
 
-   return Size+1; //NB: incl. nullterm
+    /* Return the size + the null char */
+    return (Size + sizeof(CHAR));
 }
 
-
 /*
  * @implemented
  *
  * NOTES
- *  See RtlpUnicodeStringToAnsiString
+ *  This function always writes a terminating '\0'.
+ *  It performs a partial copy if ansi is too small.
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlUnicodeStringToAnsiString(
    IN OUT PANSI_STRING AnsiDest,
-   IN PUNICODE_STRING UniSource,
+   IN PCUNICODE_STRING UniSource,
    IN BOOLEAN AllocateDestinationString)
 {
-   return RtlpUnicodeStringToAnsiString(
-             AnsiDest,
-             UniSource,
-             AllocateDestinationString,
-             NonPagedPool);
-}
+    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS RealStatus;
+    ULONG Length;
+    ULONG Index;
 
+    PAGED_CODE_RTL();
 
-/*
- * private
- *
- * NOTES
- *  This function always writes a terminating '\0'.
- *  It performs a partial copy if ansi is too small.
- */
-NTSTATUS
-FASTCALL
-RtlpUnicodeStringToAnsiString(
-   IN OUT PANSI_STRING AnsiDest,
-   IN PUNICODE_STRING UniSource,
-   IN BOOLEAN AllocateDestinationString,
-   IN POOL_TYPE PoolType)
-{
-   NTSTATUS Status = STATUS_SUCCESS;
-   ULONG Length; //including nullterm
-
-   if (NlsMbCodePageTag == TRUE)
-   {
-      Length = RtlUnicodeStringToAnsiSize(UniSource);
-   }
-   else
-      Length = (UniSource->Length / sizeof(WCHAR)) + sizeof(CHAR);
+    Length = RtlUnicodeStringToAnsiSize(UniSource);
+    if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
 
-   AnsiDest->Length = Length - sizeof(CHAR);
+    AnsiDest->Length = (USHORT)Length - sizeof(CHAR);
 
-   if (AllocateDestinationString)
-   {
-      AnsiDest->Buffer = ExAllocatePoolWithTag(PoolType, Length, TAG_ASTR);
-      if (AnsiDest->Buffer == NULL)
-         return STATUS_NO_MEMORY;
+    if (AllocateDestinationString)
+    {
+        AnsiDest->Buffer = RtlpAllocateStringMemory(Length, TAG_ASTR);
+        AnsiDest->MaximumLength = Length;
+        if (!AnsiDest->Buffer) return STATUS_NO_MEMORY;
+    }
+    else if (AnsiDest->Length >= AnsiDest->MaximumLength)
+    {
+        if (!AnsiDest->MaximumLength) return STATUS_BUFFER_OVERFLOW;
 
-      AnsiDest->MaximumLength = Length;
-   }
-   else if (AnsiDest->MaximumLength == 0)
-   {
-      return STATUS_BUFFER_TOO_SMALL;
-   }
-   else if (Length > AnsiDest->MaximumLength)
-   {
-      //make room for nullterm
-      AnsiDest->Length = AnsiDest->MaximumLength - sizeof(CHAR);
-   }
+        Status = STATUS_BUFFER_OVERFLOW;
+        AnsiDest->Length = AnsiDest->MaximumLength - 1;
+    }
 
-   Status = RtlUnicodeToMultiByteN (AnsiDest->Buffer,
-                                    AnsiDest->Length,
-                                    NULL,
-                                    UniSource->Buffer,
-                                    UniSource->Length);
+    RealStatus = RtlUnicodeToMultiByteN(AnsiDest->Buffer,
+                                        AnsiDest->Length,
+                                        &Index,
+                                        UniSource->Buffer,
+                                        UniSource->Length);
 
-   if (!NT_SUCCESS(Status) && AllocateDestinationString)
-   {
-      ExFreePool (AnsiDest->Buffer);
-      return Status;
-   }
+    if (!NT_SUCCESS(RealStatus) && AllocateDestinationString)
+    {
+        RtlpFreeStringMemory(AnsiDest->Buffer, TAG_ASTR);
+        return RealStatus;
+    }
 
-   AnsiDest->Buffer[AnsiDest->Length] = 0;
-   return Status;
+    AnsiDest->Buffer[Index] = ANSI_NULL;
+    return Status;
 }
 
-
 /*
  * @implemented
  *
  * NOTES
- *  See RtlpOemStringToUnicodeString 
+ *  This function always writes a terminating '\0'.
+ *  Does NOT perform a partial copy if unicode is too small!
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlOemStringToUnicodeString(
    IN OUT PUNICODE_STRING UniDest,
-   IN POEM_STRING OemSource,
+   IN PCOEM_STRING OemSource,
    IN BOOLEAN AllocateDestinationString)
 {
-   return RtlpOemStringToUnicodeString(
-             UniDest,
-             OemSource,
-             AllocateDestinationString,
-             NonPagedPool);
-}
+    NTSTATUS Status;
+    ULONG Length;
+    ULONG Index;
 
+    PAGED_CODE_RTL();
 
-/*
- * private
- *
- * NOTES
- *  This function always writes a terminating '\0'.
- *  Does NOT perform a partial copy if unicode is too small!
- */
-NTSTATUS
-FASTCALL
-RtlpOemStringToUnicodeString(
-   IN OUT PUNICODE_STRING UniDest,
-   IN POEM_STRING OemSource,
-   IN BOOLEAN AllocateDestinationString,
-   IN POOL_TYPE PoolType)
-{
-   NTSTATUS Status;
-   ULONG Length; //including nullterm
+    Length = RtlOemStringToUnicodeSize(OemSource);
+    if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
 
-   if (NlsMbOemCodePageTag == TRUE)
-      Length = RtlOemStringToUnicodeSize(OemSource);
-   else
-      Length = (OemSource->Length * sizeof(WCHAR)) + sizeof(WCHAR);
-
-   if (Length > 0xffff)
-      return STATUS_INVALID_PARAMETER_2;
+    UniDest->Length = (USHORT)Length - sizeof(WCHAR);
 
-   UniDest->Length = (WORD)(Length - sizeof(WCHAR));
+    if (AllocateDestinationString)
+    {
+        UniDest->Buffer = RtlpAllocateStringMemory(Length, TAG_USTR);
+        UniDest->MaximumLength = Length;
+        if (!UniDest->Buffer) return STATUS_NO_MEMORY;
+    }
+    else if (UniDest->Length >= UniDest->MaximumLength)
+    {
+        return STATUS_BUFFER_OVERFLOW;
+    }
 
-   if (AllocateDestinationString)
-   {
-      UniDest->Buffer = ExAllocatePoolWithTag(PoolType, Length, TAG_USTR);
-      if (UniDest->Buffer == NULL)
-         return STATUS_NO_MEMORY;
-
-      UniDest->MaximumLength = Length;
-   }
-   else if (Length > UniDest->MaximumLength)
-   {
-      DPRINT("STATUS_BUFFER_TOO_SMALL\n");
-      return STATUS_BUFFER_TOO_SMALL;
-   }
-
-   //FIXME: Do we need this????? -Gunnar
-   RtlZeroMemory (UniDest->Buffer,
-                  UniDest->Length);
-
-   Status = RtlOemToUnicodeN (UniDest->Buffer,
+    Status = RtlOemToUnicodeN(UniDest->Buffer,
                               UniDest->Length,
-                              NULL,
+                              &Index,
                               OemSource->Buffer,
                               OemSource->Length);
 
-   if (!NT_SUCCESS(Status) && AllocateDestinationString)
-   {
-      ExFreePool (UniDest->Buffer);
-      return Status;
-   }
+    if (!NT_SUCCESS(Status) && AllocateDestinationString)
+    {
+        RtlpFreeStringMemory(UniDest->Buffer, TAG_USTR);
+        UniDest->Buffer = NULL;
+        return Status;
+    }
 
-   UniDest->Buffer[UniDest->Length / sizeof(WCHAR)] = 0;
-   return STATUS_SUCCESS;
+    UniDest->Buffer[Index / sizeof(WCHAR)] = UNICODE_NULL;
+    return Status;
 }
 
-
 /*
  * @implemented
  *
  * NOTES
- *  See RtlpUnicodeStringToOemString.
+ *   This function always '\0' terminates the string returned.
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlUnicodeStringToOemString(
    IN OUT POEM_STRING OemDest,
-   IN PUNICODE_STRING UniSource,
+   IN PCUNICODE_STRING UniSource,
    IN BOOLEAN  AllocateDestinationString)
 {
-   return RtlpUnicodeStringToOemString(
-             OemDest,
-             UniSource,
-             AllocateDestinationString,
-             NonPagedPool);
-}
-
-
-
-/*
- * private
- *
- * NOTES
- *   This function always '\0' terminates the string returned.
- */
-NTSTATUS
-FASTCALL
-RtlpUnicodeStringToOemString(
-   IN OUT POEM_STRING OemDest,
-   IN PUNICODE_STRING UniSource,
-   IN BOOLEAN  AllocateDestinationString,
-   IN POOL_TYPE PoolType)
-{
-   NTSTATUS Status = STATUS_SUCCESS;
-   ULONG Length; //including nullterm
+    NTSTATUS Status;
+    ULONG Length;
+    ULONG Index;
 
-   if (NlsMbOemCodePageTag == TRUE)
-      Length = RtlUnicodeStringToAnsiSize (UniSource);
-   else
-      Length = (UniSource->Length / sizeof(WCHAR)) + sizeof(CHAR);
-
-   if (Length > 0x0000FFFF)
-      return STATUS_INVALID_PARAMETER_2;
+    PAGED_CODE_RTL();
 
-   OemDest->Length = (WORD)(Length - sizeof(CHAR));
+    Length = RtlUnicodeStringToOemSize(UniSource);
+    if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
 
-   if (AllocateDestinationString)
-   {
-      OemDest->Buffer = ExAllocatePoolWithTag(PoolType, Length, TAG_OSTR);
-      if (OemDest->Buffer == NULL)
-         return STATUS_NO_MEMORY;
+    OemDest->Length = (USHORT)Length - sizeof(CHAR);
 
-      OemDest->MaximumLength = Length;
-   }
-   else if (OemDest->MaximumLength == 0)
-   {
-      return STATUS_BUFFER_TOO_SMALL;
-   }
-   else if (Length > OemDest->MaximumLength)
-   {
-      //make room for nullterm
-      OemDest->Length = OemDest->MaximumLength - sizeof(CHAR);
-   }
+    if (AllocateDestinationString)
+    {
+        OemDest->Buffer = RtlpAllocateStringMemory(Length, TAG_OSTR);
+        OemDest->MaximumLength = Length;
+        if (!OemDest->Buffer) return STATUS_NO_MEMORY;
+    }
+    else if (OemDest->Length >= OemDest->MaximumLength)
+    {
+        return STATUS_BUFFER_OVERFLOW;
+    }
 
-   Status = RtlUnicodeToOemN (OemDest->Buffer,
+    Status = RtlUnicodeToOemN(OemDest->Buffer,
                               OemDest->Length,
-                              NULL,
+                              &Index,
                               UniSource->Buffer,
                               UniSource->Length);
 
-   if (!NT_SUCCESS(Status) && AllocateDestinationString)
-   {
-      ExFreePool(OemDest->Buffer);
-      return Status;
-   }
+    if (!NT_SUCCESS(Status) && AllocateDestinationString)
+    {
+        RtlpFreeStringMemory(OemDest->Buffer, TAG_OSTR);
+        OemDest->Buffer = NULL;
+        return Status;
+    }
 
-   OemDest->Buffer[OemDest->Length] = 0;
-   return Status;
+    OemDest->Buffer[Index] = ANSI_NULL;
+    return Status;
 }
 
-
-
 #define ITU_IMPLEMENTED_TESTS (IS_TEXT_UNICODE_ODD_LENGTH|IS_TEXT_UNICODE_SIGNATURE)
 
-
 /*
  * @implemented
  *
  * RETURNS
  *  The length of the string if all tests were passed, 0 otherwise.
  */
-ULONG STDCALL
+ULONG NTAPI
 RtlIsTextUnicode (PVOID Buffer,
                   ULONG Length,
                   ULONG *Flags)
@@ -1249,85 +1119,65 @@ done:
    return Length;
 }
 
-
 /*
  * @implemented
  *
  * NOTES
- *  See RtlpOemStringToCountedUnicodeString
+ *  Same as RtlOemStringToUnicodeString but doesn't write terminating null
+ *  A partial copy is NOT performed if the dest buffer is too small!
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlOemStringToCountedUnicodeString(
    IN OUT PUNICODE_STRING UniDest,
-   IN POEM_STRING OemSource,
+   IN PCOEM_STRING OemSource,
    IN BOOLEAN AllocateDestinationString)
 {
-   return RtlpOemStringToCountedUnicodeString(
-             UniDest,
-             OemSource,
-             AllocateDestinationString,
-             NonPagedPool);
-}
+    NTSTATUS Status;
+    ULONG Length;
+    ULONG Index;
 
+    PAGED_CODE_RTL();
 
-/*
- * private
- *
- * NOTES
- *  Same as RtlOemStringToUnicodeString but doesn't write terminating null
- *  A partial copy is NOT performed if the dest buffer is too small!
- */
-NTSTATUS
-FASTCALL
-RtlpOemStringToCountedUnicodeString(
-   IN OUT PUNICODE_STRING UniDest,
-   IN POEM_STRING OemSource,
-   IN BOOLEAN AllocateDestinationString,
-   IN POOL_TYPE PoolType)
-{
-   NTSTATUS Status;
-   ULONG Length; //excluding nullterm
+    Length = RtlOemStringToCountedUnicodeSize(OemSource);
 
-   if (NlsMbCodePageTag == TRUE)
-      Length = RtlOemStringToUnicodeSize(OemSource) - sizeof(WCHAR);
-   else
-      Length = OemSource->Length * sizeof(WCHAR);
+    if (!Length)
+    {
+        RtlZeroMemory(UniDest, sizeof(UNICODE_STRING));
+        return STATUS_SUCCESS;
+    }
 
-   if (Length > 65535)
-      return STATUS_INVALID_PARAMETER_2;
+    if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
 
-   if (AllocateDestinationString == TRUE)
-   {
-      UniDest->Buffer = ExAllocatePoolWithTag (PoolType, Length, TAG_USTR);
-      if (UniDest->Buffer == NULL)
-         return STATUS_NO_MEMORY;
-
-      UniDest->MaximumLength = Length;
-   }
-   else if (Length > UniDest->MaximumLength)
-   {
-      return STATUS_BUFFER_TOO_SMALL;
-   }
+    UniDest->Length = (USHORT)Length;
 
-   UniDest->Length = Length;
+    if (AllocateDestinationString)
+    {
+        UniDest->Buffer = RtlpAllocateStringMemory(Length, TAG_USTR);
+        UniDest->MaximumLength = Length;
+        if (!UniDest->Buffer) return STATUS_NO_MEMORY;
+    }
+    else if (UniDest->Length >= UniDest->MaximumLength)
+    {
+        return STATUS_BUFFER_OVERFLOW;
+    }
 
-   Status = RtlOemToUnicodeN (UniDest->Buffer,
+    Status = RtlOemToUnicodeN(UniDest->Buffer,
                               UniDest->Length,
-                              NULL,
+                              &Index,
                               OemSource->Buffer,
                               OemSource->Length);
 
-   if (!NT_SUCCESS(Status) && AllocateDestinationString)
-   {
-      ExFreePool (UniDest->Buffer);
-      return Status;
-   }
+    if (!NT_SUCCESS(Status) && AllocateDestinationString)
+    {
+        RtlpFreeStringMemory(UniDest->Buffer, TAG_USTR);
+        UniDest->Buffer = NULL;
+        return Status;
+    }
 
-   return Status;
+    return STATUS_SUCCESS;
 }
 
-
 /*
  * @implemented
  *
@@ -1338,26 +1188,30 @@ RtlpOemStringToCountedUnicodeString(
  *  The comparison is case insensitive.
  */
 BOOLEAN
-STDCALL
+NTAPI
 RtlEqualComputerName(
    IN PUNICODE_STRING ComputerName1,
    IN PUNICODE_STRING ComputerName2)
 {
-   OEM_STRING OemString1;
-   OEM_STRING OemString2;
-   BOOLEAN Result = FALSE;
+    OEM_STRING OemString1;
+    OEM_STRING OemString2;
+    BOOLEAN Result = FALSE;
 
-   if (NT_SUCCESS(RtlUpcaseUnicodeStringToOemString( &OemString1, ComputerName1, TRUE )))
-   {
-      if (NT_SUCCESS(RtlUpcaseUnicodeStringToOemString( &OemString2, ComputerName2, TRUE )))
-      {
-         Result = RtlEqualString( &OemString1, &OemString2, TRUE );
-         RtlFreeOemString( &OemString2 );
-      }
-      RtlFreeOemString( &OemString1 );
-   }
+    if (NT_SUCCESS(RtlUpcaseUnicodeStringToOemString(&OemString1,
+                                                     ComputerName1,
+                                                     TRUE)))
+    {
+        if (NT_SUCCESS(RtlUpcaseUnicodeStringToOemString(&OemString2,
+                                                         ComputerName2,
+                                                         TRUE)))
+        {
+            Result = RtlEqualString(&OemString1, &OemString2, FALSE);
+            RtlFreeOemString(&OemString2);
+        }
+        RtlFreeOemString(&OemString1);
+    }
 
-   return Result;
+    return Result;
 }
 
 /*
@@ -1370,50 +1224,15 @@ RtlEqualComputerName(
  *  The comparison is case insensitive.
  */
 BOOLEAN
-STDCALL
+NTAPI
 RtlEqualDomainName (
    IN PUNICODE_STRING DomainName1,
    IN PUNICODE_STRING DomainName2
 )
 {
-   return RtlEqualComputerName(DomainName1, DomainName2);
+    return RtlEqualComputerName(DomainName1, DomainName2);
 }
 
-
-/*
- * @implemented
- */
-/*
-BOOLEAN
-STDCALL
-RtlEqualDomainName (
-   IN PUNICODE_STRING DomainName1,
-   IN PUNICODE_STRING DomainName2
-)
-{
-   OEM_STRING OemString1;
-   OEM_STRING OemString2;
-   BOOLEAN Result;
-   RtlUpcaseUnicodeStringToOemString (&OemString1,
-                                      DomainName1,
-                                      TRUE);
-   RtlUpcaseUnicodeStringToOemString (&OemString2,
-                                      DomainName2,
-                                      TRUE);
-   Result = RtlEqualString (&OemString1,
-                            &OemString2,
-                            FALSE);
-   RtlFreeOemString (&OemString1);
-   RtlFreeOemString (&OemString2);
-   return Result;
-   
-}
-*/
-
 /*
  * @implemented
  *
@@ -1433,7 +1252,7 @@ RtlEqualDomainName (
  *  See RtlStringFromGUID.
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlGUIDFromString(
    IN UNICODE_STRING *str,
    OUT GUID* guid
@@ -1547,124 +1366,134 @@ RtlGUIDFromString(
  * @implemented
  */
 VOID
-STDCALL
+NTAPI
 RtlEraseUnicodeString(
    IN PUNICODE_STRING String)
 {
-   if (String->Buffer == NULL)
-      return;
-
-   if (String->MaximumLength == 0)
-      return;
-
-   memset (String->Buffer,
-           0,
-           String->MaximumLength);
-
-   String->Length = 0;
+    if (String->Buffer && String->MaximumLength)
+    {
+        RtlZeroMemory(String->Buffer, String->MaximumLength);
+        String->Length = 0;
+    }
 }
 
 /*
-* @unimplemented
+* @implemented
 */
 NTSTATUS
-STDCALL
+NTAPI
 RtlHashUnicodeString(
-       IN const UNICODE_STRING *String,
-       IN BOOLEAN CaseInSensitive,
-       IN ULONG HashAlgorithm,
-       OUT PULONG HashValue
-       )
-{
-       UNIMPLEMENTED;
-       return STATUS_NOT_IMPLEMENTED;
+  IN CONST UNICODE_STRING *String,
+  IN BOOLEAN CaseInSensitive,
+  IN ULONG HashAlgorithm,
+  OUT PULONG HashValue)
+{
+    if (String != NULL && HashValue != NULL)
+    {
+        switch (HashAlgorithm)
+        {
+            case HASH_STRING_ALGORITHM_DEFAULT:
+            case HASH_STRING_ALGORITHM_X65599:
+            {
+                WCHAR *c, *end;
+
+                *HashValue = 0;
+                end = String->Buffer + (String->Length / sizeof(WCHAR));
+
+                if (CaseInSensitive)
+                {
+                    for (c = String->Buffer;
+                         c != end;
+                         c++)
+                    {
+                        /* only uppercase characters if they are 'a' ... 'z'! */
+                        *HashValue = ((65599 * (*HashValue)) +
+                                      (ULONG)(((*c) >= L'a' && (*c) <= L'z') ?
+                                              (*c) - L'a' + L'A' : (*c)));
+                    }
+                }
+                else
+                {
+                    for (c = String->Buffer;
+                         c != end;
+                         c++)
+                    {
+                        *HashValue = ((65599 * (*HashValue)) + (ULONG)(*c));
+                    }
+                }
+                return STATUS_SUCCESS;
+            }
+        }
+    }
+
+    return STATUS_INVALID_PARAMETER;
 }
 
 /*
  * @implemented
  *
  * NOTES
- *  See RtlpUnicodeStringToCountedOemString.
+ *  Same as RtlUnicodeStringToOemString but doesn't write terminating null
+ *  Does a partial copy if the dest buffer is too small
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlUnicodeStringToCountedOemString(
    IN OUT POEM_STRING OemDest,
    IN PUNICODE_STRING UniSource,
    IN BOOLEAN AllocateDestinationString)
 {
-   return RtlpUnicodeStringToCountedOemString(
-             OemDest,
-             UniSource,
-             AllocateDestinationString,
-             NonPagedPool);
-}
+    NTSTATUS Status;
+    ULONG Length;
+    ULONG Index;
 
-/*
- * private
- *
- * NOTES
- *  Same as RtlUnicodeStringToOemString but doesn't write terminating null
- *  Does a partial copy if the dest buffer is too small
- */
-NTSTATUS
-FASTCALL
-RtlpUnicodeStringToCountedOemString(
-   IN OUT POEM_STRING OemDest,
-   IN PUNICODE_STRING UniSource,
-   IN BOOLEAN AllocateDestinationString,
-   IN POOL_TYPE PoolType)
-{
-   NTSTATUS Status;
-   ULONG Length; //excluding nullterm
+    PAGED_CODE_RTL();
 
-   if (NlsMbOemCodePageTag == TRUE)
-      Length = RtlUnicodeStringToAnsiSize(UniSource) - sizeof(CHAR);
-   else
-      Length = (UniSource->Length / sizeof(WCHAR));
+    Length = RtlUnicodeStringToCountedOemSize(UniSource);
 
-   if (Length > 0x0000FFFF)
-      return STATUS_INVALID_PARAMETER_2;
+    if (!Length)
+    {
+        RtlZeroMemory(OemDest, sizeof(UNICODE_STRING));
+    }
 
-   OemDest->Length = (WORD)(Length);
+    if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
 
-   if (AllocateDestinationString)
-   {
-      OemDest->Buffer = ExAllocatePoolWithTag(PoolType, Length, TAG_OSTR);
-      if (OemDest->Buffer == NULL)
-         return STATUS_NO_MEMORY;
+    OemDest->Length = (USHORT)Length;
 
-      OemDest->MaximumLength = Length;
-   }
-   else if (OemDest->MaximumLength == 0)
-   {
-      return STATUS_BUFFER_TOO_SMALL;
-   }
-   else if (Length > OemDest->MaximumLength)
-   {
-      OemDest->Length = OemDest->MaximumLength;
-   }
+    if (AllocateDestinationString)
+    {
+        OemDest->Buffer = RtlpAllocateStringMemory(Length, TAG_OSTR);
+        OemDest->MaximumLength = Length;
+        if (!OemDest->Buffer) return STATUS_NO_MEMORY;
+    }
+    else if (OemDest->Length >= OemDest->MaximumLength)
+    {
+        return STATUS_BUFFER_OVERFLOW;
+    }
 
-   Status = RtlUnicodeToOemN (OemDest->Buffer,
+    Status = RtlUnicodeToOemN(OemDest->Buffer,
                               OemDest->Length,
-                              NULL,
+                              &Index,
                               UniSource->Buffer,
                               UniSource->Length);
 
-   if (!NT_SUCCESS(Status) && AllocateDestinationString)
-   {
-      ExFreePool(OemDest->Buffer);
-   }
+    /* FIXME: Special check needed and return STATUS_UNMAPPABLE_CHARACTER */
 
-   return Status;
-}
+    if (!NT_SUCCESS(Status) && AllocateDestinationString)
+    {
+        RtlpFreeStringMemory(OemDest->Buffer, TAG_OSTR);
+        OemDest->Buffer = NULL;
+        return Status;
+    }
 
+    return Status;
+}
 
 /*
  * @implemented
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlLargeIntegerToChar(
    IN PLARGE_INTEGER Value,
    IN ULONG  Base,
@@ -1698,7 +1527,7 @@ RtlLargeIntegerToChar(
       tp++;
    }
 
-   if (tp - temp >= Length)
+   if ((ULONG)((ULONG_PTR)tp - (ULONG_PTR)temp) >= Length)
       return STATUS_BUFFER_TOO_SMALL;
 
    sp = String;
@@ -1709,337 +1538,212 @@ RtlLargeIntegerToChar(
    return STATUS_SUCCESS;
 }
 
-
-
 /*
  * @implemented
  *
  * NOTES
- *  See RtlpUpcaseUnicodeString
+ *  dest is never '\0' terminated because it may be equal to src, and src
+ *  might not be '\0' terminated. dest->Length is only set upon success.
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlUpcaseUnicodeString(
    IN OUT PUNICODE_STRING UniDest,
    IN PCUNICODE_STRING UniSource,
    IN BOOLEAN  AllocateDestinationString)
 {
+    ULONG i, j;
 
-   return RtlpUpcaseUnicodeString(
-             UniDest,
-             UniSource,
-             AllocateDestinationString,
-             NonPagedPool);
-}
+    PAGED_CODE_RTL();
 
+    if (AllocateDestinationString == TRUE)
+    {
+        UniDest->MaximumLength = UniSource->Length;
+        UniDest->Buffer = RtlpAllocateStringMemory(UniDest->MaximumLength, TAG_USTR);
+        if (UniDest->Buffer == NULL) return STATUS_NO_MEMORY;
+    }
+    else if (UniSource->Length > UniDest->MaximumLength)
+    {
+        return STATUS_BUFFER_OVERFLOW;
+    }
 
-/*
- * private
- *
- * NOTES
- *  dest is never '\0' terminated because it may be equal to src, and src
- *  might not be '\0' terminated. dest->Length is only set upon success.
- */
-NTSTATUS
-FASTCALL
-RtlpUpcaseUnicodeString(
-   IN OUT PUNICODE_STRING UniDest,
-   IN PCUNICODE_STRING UniSource,
-   IN BOOLEAN  AllocateDestinationString,
-   IN POOL_TYPE PoolType)
-{
-   ULONG i;
-   PWCHAR Src, Dest;
-
-   if (AllocateDestinationString == TRUE)
-   {
-      UniDest->MaximumLength = UniSource->Length;
-      UniDest->Buffer = ExAllocatePoolWithTag(PoolType, UniDest->MaximumLength, TAG_USTR);
-      if (UniDest->Buffer == NULL)
-         return STATUS_NO_MEMORY;
-   }
-   else if (UniSource->Length > UniDest->MaximumLength)
-   {
-      return STATUS_BUFFER_TOO_SMALL;
-   }
-
-   UniDest->Length = UniSource->Length;
+    j = UniSource->Length / sizeof(WCHAR);
 
-   Src = UniSource->Buffer;
-   Dest = UniDest->Buffer;
-   for (i = 0; i < UniSource->Length / sizeof(WCHAR); i++)
-   {
-      *Dest = RtlUpcaseUnicodeChar (*Src);
-      Dest++;
-      Src++;
-   }
+    for (i = 0; i < j; i++)
+    {
+        UniDest->Buffer[i] = RtlUpcaseUnicodeChar(UniSource->Buffer[i]);
+    }
 
-   return STATUS_SUCCESS;
+    UniDest->Length = UniSource->Length;
+    return STATUS_SUCCESS;
 }
 
-
-
 /*
  * @implemented
  *
  * NOTES
- *  See RtlpUpcaseUnicodeStringToAnsiString
- */
-NTSTATUS
-STDCALL
-RtlUpcaseUnicodeStringToAnsiString(
-   IN OUT PANSI_STRING AnsiDest,
-   IN PUNICODE_STRING UniSource,
-   IN BOOLEAN  AllocateDestinationString)
-{
-   return RtlpUpcaseUnicodeStringToAnsiString(
-             AnsiDest,
-             UniSource,
-             AllocateDestinationString,
-             NonPagedPool);
-}
-
-/*
- * private
- *
- * NOTES
  *  This function always writes a terminating '\0'.
  *  It performs a partial copy if ansi is too small.
  */
 NTSTATUS
-FASTCALL
-RtlpUpcaseUnicodeStringToAnsiString(
+NTAPI
+RtlUpcaseUnicodeStringToAnsiString(
    IN OUT PANSI_STRING AnsiDest,
    IN PUNICODE_STRING UniSource,
-   IN BOOLEAN  AllocateDestinationString,
-   IN POOL_TYPE PoolType)
+   IN BOOLEAN  AllocateDestinationString)
 {
-   NTSTATUS Status;
-   ULONG Length; //including nullterm
+    NTSTATUS Status;
+    ULONG Length;
+    ULONG Index;
 
-   if (NlsMbCodePageTag == TRUE)
-      Length = RtlUnicodeStringToAnsiSize(UniSource);
-   else
-      Length = (UniSource->Length / sizeof(WCHAR)) + sizeof(CHAR);
-
-   if (Length > 0x0000FFFF)
-      return STATUS_INVALID_PARAMETER_2;
+    PAGED_CODE_RTL();
 
-   AnsiDest->Length = (WORD)(Length - sizeof(CHAR));
+    Length = RtlUnicodeStringToAnsiSize(UniSource);
+    if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
 
-   if (AllocateDestinationString)
-   {
-      AnsiDest->Buffer = ExAllocatePoolWithTag(PoolType, Length, TAG_ASTR);
-      if (AnsiDest->Buffer == NULL)
-         return STATUS_NO_MEMORY;
-
-      AnsiDest->MaximumLength = Length;
-   }
-   else if (AnsiDest->MaximumLength == 0)
-   {
-      return STATUS_BUFFER_TOO_SMALL;
-   }
-   else if (Length > AnsiDest->MaximumLength)
-   {
-      //make room for nullterm
-      AnsiDest->Length = AnsiDest->MaximumLength - sizeof(CHAR);
-   }
+    AnsiDest->Length = (USHORT)Length - sizeof(CHAR);
 
-   //FIXME: do we need this??????? -Gunnar
-   RtlZeroMemory (AnsiDest->Buffer,
-                  AnsiDest->Length);
+    if (AllocateDestinationString)
+    {
+        AnsiDest->Buffer = RtlpAllocateStringMemory(Length, TAG_ASTR);
+        AnsiDest->MaximumLength = Length;
+        if (!AnsiDest->Buffer) return STATUS_NO_MEMORY;
+    }
+    else if (AnsiDest->Length >= AnsiDest->MaximumLength)
+    {
+        if (!AnsiDest->MaximumLength) return STATUS_BUFFER_OVERFLOW;
+    }
 
-   Status = RtlUpcaseUnicodeToMultiByteN (AnsiDest->Buffer,
+    Status = RtlUpcaseUnicodeToMultiByteN(AnsiDest->Buffer,
                                           AnsiDest->Length,
-                                          NULL,
+                                          &Index,
                                           UniSource->Buffer,
                                           UniSource->Length);
 
-   if (!NT_SUCCESS(Status) && AllocateDestinationString)
-   {
-      ExFreePool(AnsiDest->Buffer);
-      return Status;
-   }
+    if (!NT_SUCCESS(Status) && AllocateDestinationString)
+    {
+        RtlpFreeStringMemory(AnsiDest->Buffer, TAG_ASTR);
+        AnsiDest->Buffer = NULL;
+        return Status;
+    }
 
-   AnsiDest->Buffer[AnsiDest->Length] = 0;
-   return Status;
+    AnsiDest->Buffer[Index] = ANSI_NULL;
+    return Status;
 }
 
-
-
 /*
  * @implemented
  *
  * NOTES
- *  See RtlpUpcaseUnicodeStringToCountedOemString
+ *  This function always writes a terminating '\0'.
+ *  It performs a partial copy if ansi is too small.
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlUpcaseUnicodeStringToCountedOemString(
    IN OUT POEM_STRING OemDest,
-   IN PUNICODE_STRING UniSource,
+   IN PCUNICODE_STRING UniSource,
    IN BOOLEAN AllocateDestinationString)
 {
-   return RtlpUpcaseUnicodeStringToCountedOemString(
-             OemDest,
-             UniSource,
-             AllocateDestinationString,
-             NonPagedPool);
-}
-
+    NTSTATUS Status;
+    ULONG Length;
+    ULONG Index;
 
+    PAGED_CODE_RTL();
 
-/*
- * private
- *
- * NOTES
- *  Same as RtlUpcaseUnicodeStringToOemString but doesn't write terminating null
- *  It performs a partial copy if oem is too small.
- */
-NTSTATUS
-FASTCALL
-RtlpUpcaseUnicodeStringToCountedOemString(
-   IN OUT POEM_STRING OemDest,
-   IN PUNICODE_STRING UniSource,
-   IN BOOLEAN AllocateDestinationString,
-   IN POOL_TYPE PoolType)
-{
-   NTSTATUS Status;
-   ULONG Length; //excluding nullterm
+    Length = RtlUnicodeStringToCountedOemSize(UniSource);
 
-   if (NlsMbCodePageTag == TRUE)
-      Length = RtlUnicodeStringToAnsiSize(UniSource) - sizeof(CHAR);
-   else
-      Length = UniSource->Length / sizeof(WCHAR);
+    if (!Length)
+    {
+        RtlZeroMemory(OemDest, sizeof(UNICODE_STRING));
+    }
 
-   if (Length > 0x0000FFFF)
-      return(STATUS_INVALID_PARAMETER_2);
+    if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
 
-   OemDest->Length = (WORD)(Length);
+    OemDest->Length = (USHORT)Length;
 
-   if (AllocateDestinationString)
-   {
-      OemDest->Buffer = ExAllocatePoolWithTag(PoolType, Length, TAG_OSTR);
-      if (OemDest->Buffer == NULL)
-         return(STATUS_NO_MEMORY);
+    if (AllocateDestinationString)
+    {
+        OemDest->Buffer = RtlpAllocateStringMemory(Length, TAG_OSTR);
+        OemDest->MaximumLength = Length;
+        if (!OemDest->Buffer) return STATUS_NO_MEMORY;
+    }
+    else if (OemDest->Length >= OemDest->MaximumLength)
+    {
+        return STATUS_BUFFER_OVERFLOW;
+    }
 
-      //FIXME: Do we need this?????
-      RtlZeroMemory (OemDest->Buffer, Length);
-
-      OemDest->MaximumLength = (WORD)Length;
-   }
-   else if (OemDest->MaximumLength == 0)
-   {
-      return(STATUS_BUFFER_TOO_SMALL);
-   }
-   else if (Length > OemDest->MaximumLength)
-   {
-      OemDest->Length = OemDest->MaximumLength;
-   }
+    Status = RtlUpcaseUnicodeToOemN(OemDest->Buffer,
+                                    OemDest->Length,
+                                    &Index,
+                                    UniSource->Buffer,
+                                    UniSource->Length);
 
-   Status = RtlUpcaseUnicodeToOemN(OemDest->Buffer,
-                                   OemDest->Length,
-                                   NULL,
-                                   UniSource->Buffer,
-                                   UniSource->Length);
+    /* FIXME: Special check needed and return STATUS_UNMAPPABLE_CHARACTER */
 
-   if (!NT_SUCCESS(Status) && AllocateDestinationString)
-   {
-      ExFreePool(OemDest->Buffer);
-      return Status;
-   }
+    if (!NT_SUCCESS(Status) && AllocateDestinationString)
+    {
+        RtlpFreeStringMemory(OemDest->Buffer, TAG_OSTR);
+        OemDest->Buffer = NULL;
+        return Status;
+    }
 
-   return Status;
+    return Status;
 }
 
-
 /*
  * @implemented
  * NOTES
- *  See RtlpUpcaseUnicodeStringToOemString
- */
-NTSTATUS
-STDCALL
-RtlUpcaseUnicodeStringToOemString (
-   IN OUT POEM_STRING OemDest,
-   IN PUNICODE_STRING UniSource,
-   IN BOOLEAN  AllocateDestinationString
-)
-{
-   return RtlpUpcaseUnicodeStringToOemString(
-             OemDest,
-             UniSource,
-             AllocateDestinationString,
-             NonPagedPool);
-}
-
-
-/*
- * private
- *
- * NOTES
- *  Oem string is allways nullterminated 
+ *  Oem string is allways nullterminated
  *  It performs a partial copy if oem is too small.
  */
 NTSTATUS
-FASTCALL
-RtlpUpcaseUnicodeStringToOemString (
+NTAPI
+RtlUpcaseUnicodeStringToOemString (
    IN OUT POEM_STRING OemDest,
-   IN PUNICODE_STRING UniSource,
-   IN BOOLEAN  AllocateDestinationString,
-   IN POOL_TYPE PoolType
-)
+   IN PCUNICODE_STRING UniSource,
+   IN BOOLEAN  AllocateDestinationString)
 {
-   NTSTATUS Status;
-   ULONG Length; //including nullterm
+    NTSTATUS Status;
+    ULONG Length;
+    ULONG Index;
 
-   if (NlsMbOemCodePageTag == TRUE)
-      Length = RtlUnicodeStringToAnsiSize(UniSource);
-   else
-      Length = (UniSource->Length / sizeof(WCHAR)) + sizeof(CHAR);
+    PAGED_CODE_RTL();
 
-   if (Length > 0x0000FFFF)
-      return STATUS_INVALID_PARAMETER_2;
+    Length = RtlUnicodeStringToOemSize(UniSource);
+    if (Length > MAXUSHORT) return STATUS_INVALID_PARAMETER_2;
 
-   OemDest->Length = (WORD)(Length - sizeof(CHAR));
+    OemDest->Length = (USHORT)Length - sizeof(CHAR);
 
-   if (AllocateDestinationString)
-   {
-      OemDest->Buffer = ExAllocatePoolWithTag(PoolType, Length, TAG_OSTR);
-      if (OemDest->Buffer == NULL)
-         return STATUS_NO_MEMORY;
-
-      //FIXME: Do we need this????
-      RtlZeroMemory (OemDest->Buffer, Length);
-
-      OemDest->MaximumLength = (WORD)Length;
-   }
-   else if (OemDest->MaximumLength == 0)
-   {
-      return STATUS_BUFFER_OVERFLOW;
-   }
-   else if (Length > OemDest->MaximumLength)
-   {
-      //make room for nullterm
-      OemDest->Length = OemDest->MaximumLength - sizeof(CHAR);
-   }
+    if (AllocateDestinationString)
+    {
+        OemDest->Buffer = RtlpAllocateStringMemory(Length, TAG_OSTR);
+        OemDest->MaximumLength = Length;
+        if (!OemDest->Buffer) return STATUS_NO_MEMORY;
+    }
+    else if (OemDest->Length >= OemDest->MaximumLength)
+    {
+        return STATUS_BUFFER_OVERFLOW;
+    }
 
-   Status = RtlUpcaseUnicodeToOemN (OemDest->Buffer,
+    Status = RtlUpcaseUnicodeToOemN(OemDest->Buffer,
                                     OemDest->Length,
-                                    NULL,
+                                    &Index,
                                     UniSource->Buffer,
                                     UniSource->Length);
 
-   if (!NT_SUCCESS(Status) && AllocateDestinationString)
-   {
-      ExFreePool(OemDest->Buffer);
-      return Status;
-   }
+    /* FIXME: Special check needed and return STATUS_UNMAPPABLE_CHARACTER */
 
-   OemDest->Buffer[OemDest->Length] = 0;
-   return Status;
-}
+    if (!NT_SUCCESS(Status) && AllocateDestinationString)
+    {
+        RtlpFreeStringMemory(OemDest->Buffer, TAG_OSTR);
+        OemDest->Buffer = NULL;
+        return Status;
+    }
 
+    OemDest->Buffer[Index] = ANSI_NULL;
+    return Status;
+}
 
 /*
  * @implemented
@@ -2048,30 +1752,29 @@ RtlpUpcaseUnicodeStringToOemString (
  *  Bytes calculated including nullterm
  */
 ULONG
-STDCALL
-RtlOemStringToUnicodeSize(IN POEM_STRING OemString)
+NTAPI
+RtlxOemStringToUnicodeSize(IN PCOEM_STRING OemString)
 {
-   ULONG Size;
+    ULONG Size;
 
-   //this function returns size including nullterm
-   RtlMultiByteToUnicodeSize(&Size,
-                             OemString->Buffer,
-                             OemString->Length);
+    /* Convert the Mb String to Unicode Size */
+    RtlMultiByteToUnicodeSize(&Size,
+                              OemString->Buffer,
+                              OemString->Length);
 
-   return(Size);
+    /* Return the size + null-char */
+    return (Size + sizeof(WCHAR));
 }
 
-
-
 /*
  * @implemented
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlStringFromGUID (IN REFGUID Guid,
                    OUT PUNICODE_STRING GuidString)
 {
-   STATIC CONST PWCHAR Hex = L"0123456789ABCDEF";
+   static CONST PWCHAR Hex = L"0123456789ABCDEF";
    WCHAR Buffer[40];
    PWCHAR BufferPtr;
    ULONG i;
@@ -2103,7 +1806,6 @@ RtlStringFromGUID (IN REFGUID Guid,
    return RtlCreateUnicodeString (GuidString, Buffer);
 }
 
-
 /*
  * @implemented
  *
@@ -2111,283 +1813,227 @@ RtlStringFromGUID (IN REFGUID Guid,
  *  Bytes calculated including nullterm
  */
 ULONG
-STDCALL
-RtlUnicodeStringToAnsiSize(
-   IN PUNICODE_STRING UnicodeString)
+NTAPI
+RtlxUnicodeStringToAnsiSize(IN PCUNICODE_STRING UnicodeString)
 {
-   ULONG Size;
+    ULONG Size;
 
-   //this function return size without nullterm!
-   RtlUnicodeToMultiByteSize (&Size,
+    /* Convert the Unicode String to Mb Size */
+    RtlUnicodeToMultiByteSize(&Size,
                               UnicodeString->Buffer,
                               UnicodeString->Length);
 
-   return Size + sizeof(CHAR); //NB: incl. nullterm
+    /* Return the size + null-char */
+    return (Size + sizeof(CHAR));
 }
 
-
-
-
 /*
  * @implemented
  */
 LONG
-STDCALL
+NTAPI
 RtlCompareUnicodeString(
-   IN PUNICODE_STRING String1,
-   IN PUNICODE_STRING String2,
+   IN PCUNICODE_STRING s1,
+   IN PCUNICODE_STRING s2,
    IN BOOLEAN  CaseInsensitive)
 {
-   ULONG len1, len2;
-   PWCHAR s1, s2;
-   WCHAR  c1, c2;
+   unsigned int len;
+   LONG ret = 0;
+   LPCWSTR p1, p2;
 
-   if (String1 && String2)
-   {
-      len1 = String1->Length / sizeof(WCHAR);
-      len2 = String2->Length / sizeof(WCHAR);
-      s1 = String1->Buffer;
-      s2 = String2->Buffer;
+   len = min(s1->Length, s2->Length) / sizeof(WCHAR);
+   p1 = s1->Buffer;
+   p2 = s2->Buffer;
 
-      if (s1 && s2)
-      {
-         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;
-            }
-         }
-      }
+   if (CaseInsensitive)
+   {
+     while (!ret && len--) ret = RtlUpcaseUnicodeChar(*p1++) - RtlUpcaseUnicodeChar(*p2++);
    }
-
-   return 0;
+   else
+   {
+     while (!ret && len--) ret = *p1++ - *p2++;
+   }
+   if (!ret) ret = s1->Length - s2->Length;
+   return ret;
 }
 
-
 /*
  * @implemented
  */
 VOID
-STDCALL
+NTAPI
 RtlCopyString(
    IN OUT PSTRING DestinationString,
-   IN PSTRING SourceString)
+   IN PSTRING SourceString OPTIONAL)
 {
-   ULONG copylen;
+    ULONG SourceLength;
+    PCHAR p1, p2;
 
-   if(SourceString == NULL)
-   {
-      DestinationString->Length = 0;
-      return;
-   }
+    /* Check if there was no source given */
+    if(!SourceString)
+    {
+        /* Simply return an empty string */
+        DestinationString->Length = 0;
+    }
+    else
+    {
+        /* Choose the smallest length */
+        SourceLength = min(DestinationString->MaximumLength,
+                           SourceString->Length);
 
-   copylen = min (DestinationString->MaximumLength,
-                  SourceString->Length);
-
-   memcpy(DestinationString->Buffer, SourceString->Buffer, copylen);
-   if (DestinationString->MaximumLength >= copylen + sizeof(CHAR))
-   {
-      DestinationString->Buffer[copylen] = 0;
-   }
-   DestinationString->Length = copylen;
-}
+        /* Set it */
+        DestinationString->Length = (USHORT)SourceLength;
 
+        /* Save the pointers to each buffer */
+        p1 = DestinationString->Buffer;
+        p2 = SourceString->Buffer;
 
+        /* Loop the buffer */
+        while (SourceLength)
+        {
+            /* Copy the character and move on */
+            *p1++ = * p2++;
+            SourceLength--;
+        }
+    }
+}
 
 /*
  * @implemented
  */
 VOID
-STDCALL
+NTAPI
 RtlCopyUnicodeString(
    IN OUT PUNICODE_STRING DestinationString,
-   IN PUNICODE_STRING SourceString)
+   IN PCUNICODE_STRING SourceString)
 {
-   ULONG copylen;
+    ULONG SourceLength;
 
-   if (SourceString == NULL)
-   {
-      DestinationString->Length = 0;
-      return;
-   }
+    if(SourceString == NULL)
+    {
+        DestinationString->Length = 0;
+    }
+    else
+    {
+        SourceLength = min(DestinationString->MaximumLength,
+                           SourceString->Length);
+        DestinationString->Length = (USHORT)SourceLength;
 
-   copylen = min (DestinationString->MaximumLength,
-                  SourceString->Length);
-   memcpy(DestinationString->Buffer, SourceString->Buffer, copylen);
-   if (DestinationString->MaximumLength >= copylen + sizeof(WCHAR))
-   {
-     DestinationString->Buffer[copylen / sizeof(WCHAR)] = 0;
-   }
-   DestinationString->Length = copylen;
-}
+        RtlCopyMemory(DestinationString->Buffer,
+                      SourceString->Buffer,
+                      SourceLength);
 
+        if (DestinationString->Length < DestinationString->MaximumLength)
+        {
+            DestinationString->Buffer[SourceLength / sizeof(WCHAR)] = UNICODE_NULL;
+        }
+    }
+}
 
 /*
  * @implemented
  *
  * NOTES
- *  See RtlpCreateUnicodeString
+ * Creates a nullterminated UNICODE_STRING
  */
 BOOLEAN
-STDCALL
+NTAPI
 RtlCreateUnicodeString(
    IN OUT PUNICODE_STRING UniDest,
    IN PCWSTR  Source)
 {
+    ULONG Length;
 
-   DPRINT("RtlCreateUnicodeString\n");
-   return RtlpCreateUnicodeString(UniDest, Source, NonPagedPool);
-}
-
-
-/*
- * private
- */
-BOOLEAN
-FASTCALL
-RtlpCreateUnicodeString(
-   IN OUT PUNICODE_STRING UniDest,
-   IN PCWSTR  Source,
-   IN POOL_TYPE PoolType)
-{
-   ULONG Length;
+    PAGED_CODE_RTL();
 
-   Length = (wcslen (Source) + 1) * sizeof(WCHAR);
+    Length = (wcslen(Source) + 1) * sizeof(WCHAR);
+    if (Length > 0xFFFE) return FALSE;
 
-   UniDest->Buffer = ExAllocatePoolWithTag(PoolType, Length, TAG_USTR);
-   if (UniDest->Buffer == NULL)
-      return FALSE;
+    UniDest->Buffer = RtlpAllocateStringMemory(Length, TAG_USTR);
 
-   memmove (UniDest->Buffer,
-            Source,
-            Length);
+    if (UniDest->Buffer == NULL) return FALSE;
 
-   UniDest->MaximumLength = Length;
-   UniDest->Length = Length - sizeof (WCHAR);
+    RtlCopyMemory(UniDest->Buffer, Source, Length);
+    UniDest->MaximumLength = (USHORT)Length;
+    UniDest->Length = Length - sizeof (WCHAR);
 
-   return TRUE;
+    return TRUE;
 }
 
-
-
 /*
  * @implemented
  */
 BOOLEAN
-STDCALL
+NTAPI
 RtlCreateUnicodeStringFromAsciiz(
    OUT PUNICODE_STRING Destination,
-   IN PCSZ  Source)
+   IN PCSZ Source)
 {
-   ANSI_STRING AnsiString;
-   NTSTATUS Status;
+    ANSI_STRING AnsiString;
+    NTSTATUS Status;
 
-   RtlInitAnsiString (&AnsiString,
-                      Source);
+    RtlInitAnsiString(&AnsiString, Source);
 
-   Status = RtlAnsiStringToUnicodeString (Destination,
+    Status = RtlAnsiStringToUnicodeString(Destination,
                                           &AnsiString,
                                           TRUE);
 
-   return NT_SUCCESS(Status);
+    return NT_SUCCESS(Status);
 }
 
-
-
 /*
  * @implemented
  *
  * NOTES
- *  See RtlpDowncaseUnicodeString
- */
-NTSTATUS STDCALL
-RtlDowncaseUnicodeString(
-   IN OUT PUNICODE_STRING UniDest,
-   IN PUNICODE_STRING UniSource,
-   IN BOOLEAN AllocateDestinationString)
-{
-   return RtlpDowncaseUnicodeString(
-             UniDest,
-             UniSource,
-             AllocateDestinationString,
-             NonPagedPool);
-}
-
-
-/*
- * private
- *
- * NOTES
  *  Dest is never '\0' terminated because it may be equal to src, and src
- *  might not be '\0' terminated. 
+ *  might not be '\0' terminated.
  *  Dest->Length is only set upon success.
  */
 NTSTATUS
-FASTCALL
-RtlpDowncaseUnicodeString(
+NTAPI
+RtlDowncaseUnicodeString(
    IN OUT PUNICODE_STRING UniDest,
-   IN PUNICODE_STRING UniSource,
-   IN BOOLEAN AllocateDestinationString,
-   IN POOL_TYPE PoolType)
+   IN PCUNICODE_STRING UniSource,
+   IN BOOLEAN AllocateDestinationString)
 {
-   ULONG i;
-   PWCHAR Src, Dest;
-
-   if (AllocateDestinationString)
-   {
-      UniDest->Buffer = ExAllocatePoolWithTag(PoolType, UniSource->Length, TAG_USTR);
-      if (UniDest->Buffer == NULL)
-         return STATUS_NO_MEMORY;
-
-      UniDest->MaximumLength = UniSource->Length;
-   }
-   else if (UniSource->Length > UniDest->MaximumLength)
-   {
-      return STATUS_BUFFER_TOO_SMALL;
-   }
-
-   UniDest->Length = UniSource->Length;
-
-   Src = UniSource->Buffer;
-   Dest = UniDest->Buffer;
-   for (i=0; i < UniSource->Length / sizeof(WCHAR); i++)
-   {
-      if (*Src < L'A')
-      {
-         *Dest = *Src;
-      }
-      else if (*Src <= L'Z')
-      {
-         *Dest = (*Src + (L'a' - L'A'));
-      }
-      else
-      {
-         *Dest = RtlDowncaseUnicodeChar(*Src);
-      }
-
-      Dest++;
-      Src++;
-   }
-
-   return STATUS_SUCCESS;
+    ULONG i;
+    ULONG StopGap;
+
+    PAGED_CODE_RTL();
+
+    if (AllocateDestinationString)
+    {
+        UniDest->MaximumLength = UniSource->Length;
+        UniDest->Buffer = RtlpAllocateStringMemory(UniSource->Length, TAG_USTR);
+        if (UniDest->Buffer == NULL) return STATUS_NO_MEMORY;
+    }
+    else if (UniSource->Length > UniDest->MaximumLength)
+    {
+        return STATUS_BUFFER_OVERFLOW;
+    }
+
+    UniDest->Length = UniSource->Length;
+    StopGap = UniSource->Length / sizeof(WCHAR);
+
+    for (i= 0 ; i < StopGap; i++)
+    {
+        if (UniSource->Buffer[i] < L'A')
+        {
+            UniDest->Buffer[i] = UniSource->Buffer[i];
+        }
+        else if (UniSource->Buffer[i] <= L'Z')
+        {
+            UniDest->Buffer[i] = (UniSource->Buffer[i] + (L'a' - L'A'));
+        }
+        else
+        {
+            UniDest->Buffer[i] = RtlDowncaseUnicodeChar(UniSource->Buffer[i]);
+        }
+    }
+
+    return STATUS_SUCCESS;
 }
 
-
-
 /*
  * @implemented
  *
@@ -2396,113 +2042,40 @@ RtlpDowncaseUnicodeString(
  *  dest is '\0' terminated when the MaximumLength allowes it.
  *  When dest fits exactly in MaximumLength characters the '\0' is ommitted.
  */
-NTSTATUS STDCALL
+NTSTATUS
+NTAPI
 RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination,
                          IN PCWSTR Source)
 {
-   ULONG slen;
+    USHORT Length;
+    PWCHAR DestBuffer;
 
-   slen = wcslen(Source) * sizeof(WCHAR);
+    if (Source)
+    {
+        UNICODE_STRING UnicodeSource;
 
-   if (Destination->Length + slen > Destination->MaximumLength)
-      return(STATUS_BUFFER_TOO_SMALL);
+        RtlInitUnicodeString(&UnicodeSource, Source);
+        Length = UnicodeSource.Length;
 
-   memcpy((char*)Destination->Buffer + Destination->Length, Source, slen);
-   Destination->Length += slen;
-   /* append terminating '\0' if enough space */
-   if( Destination->MaximumLength > Destination->Length )
-      Destination->Buffer[Destination->Length / sizeof(WCHAR)] = 0;
+        if (Destination->Length + Length > Destination->MaximumLength)
+        {
+            return STATUS_BUFFER_TOO_SMALL;
+        }
 
-   return(STATUS_SUCCESS);
-}
+        DestBuffer = &Destination->Buffer[Destination->Length / sizeof(WCHAR)];
+        RtlMoveMemory(DestBuffer, Source, Length);
+        Destination->Length += Length;
 
+        /* append terminating '\0' if enough space */
+        if(Destination->MaximumLength > Destination->Length)
+        {
+            DestBuffer[Length / sizeof(WCHAR)] = UNICODE_NULL;
+        }
+    }
 
-/*
- * @implemented
- *
- * NOTES
- *  See RtlpAnsiStringToUnicodeString
- */
-NTSTATUS
-STDCALL
-RtlAnsiStringToUnicodeString(
-   IN OUT PUNICODE_STRING UniDest,
-   IN PANSI_STRING AnsiSource,
-   IN BOOLEAN AllocateDestinationString)
-{
-   return RtlpAnsiStringToUnicodeString(
-             UniDest,
-             AnsiSource,
-             AllocateDestinationString,
-             NonPagedPool);
+    return STATUS_SUCCESS;
 }
 
-
-
-/*
- * private
- *
- * NOTES
- *  This function always writes a terminating '\0'.
- *  If the dest buffer is too small a partial copy is NOT performed!
- */
-NTSTATUS
-FASTCALL
-RtlpAnsiStringToUnicodeString(
-   IN OUT PUNICODE_STRING UniDest,
-   IN PANSI_STRING AnsiSource,
-   IN BOOLEAN AllocateDestinationString,
-   IN POOL_TYPE PoolType)
-{
-   NTSTATUS Status;
-   ULONG Length; //including nullterm
-
-   if (NlsMbCodePageTag == TRUE)
-      Length = RtlAnsiStringToUnicodeSize(AnsiSource);
-   else
-      Length = (AnsiSource->Length * sizeof(WCHAR)) + sizeof(WCHAR);
-
-   if (Length > 0xffff)
-      return STATUS_INVALID_PARAMETER_2;
-
-   if (AllocateDestinationString == TRUE)
-   {
-      UniDest->Buffer = ExAllocatePoolWithTag(PoolType, Length, TAG_USTR);
-      if (UniDest->Buffer == NULL)
-         return STATUS_NO_MEMORY;
-
-      UniDest->MaximumLength = Length;
-   }
-   else if (Length > UniDest->MaximumLength)
-   {
-      DPRINT("STATUS_BUFFER_TOO_SMALL\n");
-      return STATUS_BUFFER_TOO_SMALL;
-   }
-
-   UniDest->Length = Length - sizeof(WCHAR);
-
-   //FIXME: We don't need this??? -Gunnar
-   RtlZeroMemory (UniDest->Buffer,
-                  UniDest->Length);
-
-   Status = RtlMultiByteToUnicodeN (UniDest->Buffer,
-                                    UniDest->Length,
-                                    NULL,
-                                    AnsiSource->Buffer,
-                                    AnsiSource->Length);
-
-   if (!NT_SUCCESS(Status) && AllocateDestinationString)
-   {
-      ExFreePool(UniDest->Buffer);
-      return Status;
-   }
-
-   UniDest->Buffer[UniDest->Length / sizeof(WCHAR)] = 0;
-   return Status;
-}
-
-
-
 /*
  * @implemented
  *
@@ -2511,139 +2084,75 @@ RtlpAnsiStringToUnicodeString(
  *  dest is never '\0' terminated.
  */
 NTSTATUS
-STDCALL
+NTAPI
 RtlAppendAsciizToString(
    IN OUT   PSTRING  Destination,
    IN PCSZ  Source)
 {
-   ULONG Length;
-   PCHAR Ptr;
+    ULONG Length;
 
-   if (Source == NULL)
-      return STATUS_SUCCESS;
+    if (Source)
+    {
+        Length = (USHORT)strlen(Source);
 
-   Length = strlen (Source);
-   if (Destination->Length + Length >= Destination->MaximumLength)
-      return STATUS_BUFFER_TOO_SMALL;
-
-   Ptr = Destination->Buffer + Destination->Length;
-   memmove (Ptr,
-            Source,
-            Length);
-   Ptr += Length;
-   *Ptr = 0;
+        if (Destination->Length + Length > Destination->MaximumLength)
+        {
+            return STATUS_BUFFER_TOO_SMALL;
+        }
 
-   Destination->Length += Length;
+        RtlMoveMemory(&Destination->Buffer[Destination->Length], Source, Length);
+        Destination->Length += Length;
+    }
 
-   return STATUS_SUCCESS;
+    return STATUS_SUCCESS;
 }
 
-
 /*
  * @implemented
  */
-VOID STDCALL
+VOID
+NTAPI
 RtlUpperString(PSTRING DestinationString,
                PSTRING SourceString)
 {
-   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;
-}
-
-
-/*
- * @implemented
- */
-ULONG STDCALL
-RtlxAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
-{
-   return RtlAnsiStringToUnicodeSize(AnsiString);
-}
-
-
-/*
- * @implemented
- */
-ULONG STDCALL
-RtlxOemStringToUnicodeSize(IN POEM_STRING OemString)
-{
-   return RtlOemStringToUnicodeSize((PANSI_STRING)OemString);
-}
-
-
-
-/*
- * @implemented
- */
-ULONG STDCALL
-RtlxUnicodeStringToAnsiSize(IN PUNICODE_STRING UnicodeString)
-{
-   return RtlUnicodeStringToAnsiSize(UnicodeString);
-}
+    ULONG Length;
+    PCHAR Src, Dest;
 
+    Length = min(SourceString->Length,
+                 DestinationString->MaximumLength - 1);
 
-/*
- * @implemented
- */
-ULONG STDCALL
-RtlxUnicodeStringToOemSize(IN PUNICODE_STRING UnicodeString)
-{
-   return RtlUnicodeStringToOemSize(UnicodeString);
+    Src = SourceString->Buffer;
+    Dest = DestinationString->Buffer;
+    DestinationString->Length = Length;
+    while (Length)
+    {
+        *Dest++ = RtlUpperChar(*Src++);
+        Length--;
+    }
 }
 
-
 /*
  * @implemented
  *
  * NOTES
  *  See RtlpDuplicateUnicodeString
  */
-NTSTATUS STDCALL
+NTSTATUS
+NTAPI
 RtlDuplicateUnicodeString(
-   INT AddNull,
-   IN PUNICODE_STRING SourceString,
-   PUNICODE_STRING DestinationString)
-{
-   return RtlpDuplicateUnicodeString(
-            AddNull,
-            SourceString,
-            DestinationString,
-            NonPagedPool);
-}
-   
-   
-/*
- * @implemented
- */
-NTSTATUS STDCALL
-RtlpDuplicateUnicodeString(
-   INT AddNull,
-   IN PUNICODE_STRING SourceString,
-   PUNICODE_STRING DestinationString,
-   POOL_TYPE PoolType)
+   IN ULONG Flags,
+   IN PCUNICODE_STRING SourceString,
+   OUT PUNICODE_STRING DestinationString)
 {
+   PAGED_CODE_RTL();
+
    if (SourceString == NULL || DestinationString == NULL)
       return STATUS_INVALID_PARAMETER;
 
 
-   if (SourceString->Length == 0 && AddNull != 3)
+   if ((SourceString->Length == 0) && 
+       (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE | 
+                  RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING)))
    {
       DestinationString->Length = 0;
       DestinationString->MaximumLength = 0;
@@ -2651,12 +2160,12 @@ RtlpDuplicateUnicodeString(
    }
    else
    {
-      unsigned int DestMaxLength = SourceString->Length;
+      UINT DestMaxLength = SourceString->Length;
 
-      if (AddNull)
+      if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
          DestMaxLength += sizeof(UNICODE_NULL);
 
-      DestinationString->Buffer = ExAllocatePool(PoolType, DestMaxLength);
+      DestinationString->Buffer = RtlpAllocateStringMemory(DestMaxLength, TAG_USTR);
       if (DestinationString->Buffer == NULL)
          return STATUS_NO_MEMORY;
 
@@ -2664,11 +2173,39 @@ RtlpDuplicateUnicodeString(
       DestinationString->Length = SourceString->Length;
       DestinationString->MaximumLength = DestMaxLength;
 
-      if (AddNull)
+      if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
          DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0;
    }
 
    return STATUS_SUCCESS;
 }
 
+/*
+ * @implemented
+ */
+NTSTATUS NTAPI
+RtlValidateUnicodeString(IN ULONG Flags,
+                         IN PUNICODE_STRING UnicodeString)
+{
+  /* currently no flags are supported! */
+  ASSERT(Flags == 0);
+
+  if ((Flags == 0) &&
+      ((UnicodeString == NULL) ||
+       ((UnicodeString->Length != 0) &&
+        (UnicodeString->Buffer != NULL) &&
+        ((UnicodeString->Length % sizeof(WCHAR)) == 0) &&
+        ((UnicodeString->MaximumLength % sizeof(WCHAR)) == 0) &&
+        (UnicodeString->MaximumLength >= UnicodeString->Length))))
+  {
+    /* a NULL pointer as a unicode string is considered to be a valid unicode
+       string! */
+    return STATUS_SUCCESS;
+  }
+  else
+  {
+    return STATUS_INVALID_PARAMETER;
+  }
+}
+
 /* EOF */