Revert previous commit
[reactos.git] / reactos / include / ddk / ntstrsafe.h
index dccbb20..c107a0d 100644 (file)
-/*\r
- * PROJECT:         ReactOS Kernel\r
- * LICENSE:         GPL - See COPYING in the top level directory\r
- * FILE:            include/ddk/ntstrsafe.h\r
- * PURPOSE:         Safe String Library for NT Code (Native/Kernel)\r
- * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)\r
- */\r
-\r
-/* INCLUDES ******************************************************************/\r
-\r
-#ifndef _NTSTRSAFE_H_INCLUDED_\r
-#define _NTSTRSAFE_H_INCLUDED_\r
-\r
-//\r
-// Dependencies\r
-//\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <stdarg.h>\r
-\r
-//\r
-// Maximum limits: allow overriding the maximum\r
-//\r
-#ifndef NTSTRSAFE_MAX_CCH\r
-#define NTSTRSAFE_MAX_CCH       2147483647\r
-#endif\r
-#define NTSTRSAFE_MAX_LENGTH    (NTSTRSAFE_MAX_CCH - 1)\r
-\r
-/* PRIVATE FUNCTIONS *********************************************************/\r
-\r
-FORCEINLINE\r
-NTSTATUS\r
-NTAPI\r
-RtlStringLengthWorkerA(IN PCHAR String,\r
-                       IN SIZE_T MaxLength,\r
-                       OUT PSIZE_T ReturnLength OPTIONAL)\r
-{\r
-    NTSTATUS Status = STATUS_SUCCESS;\r
-    SIZE_T LocalMax = MaxLength;\r
-\r
-    while (MaxLength && (*String != ANSI_NULL))\r
-    {\r
-        String++;\r
-        MaxLength--;\r
-    }\r
-\r
-    if (!MaxLength) Status = STATUS_INVALID_PARAMETER;\r
-\r
-    if (ReturnLength)\r
-    {\r
-        if (NT_SUCCESS(Status))\r
-        {\r
-            *ReturnLength = LocalMax - MaxLength;\r
-        }\r
-        else\r
-        {\r
-            *ReturnLength = 0;\r
-        }\r
-    }\r
-\r
-    return Status;\r
-}\r
-\r
-FORCEINLINE\r
-NTSTATUS\r
-NTAPI\r
-RtlStringValidateDestA(IN PCHAR Destination,\r
-                       IN SIZE_T Length,\r
-                       OUT PSIZE_T ReturnLength OPTIONAL,\r
-                       IN SIZE_T MaxLength)\r
-{\r
-    NTSTATUS Status = STATUS_SUCCESS;\r
-\r
-    if (!(Length) || (Length > MaxLength)) Status = STATUS_INVALID_PARAMETER;\r
-\r
-    if (ReturnLength)\r
-    {\r
-        if (NT_SUCCESS(Status))\r
-        {\r
-            Status = RtlStringLengthWorkerA(Destination,\r
-                                            Length,\r
-                                            ReturnLength);\r
-        }\r
-        else\r
-        {\r
-            *ReturnLength = 0;\r
-        }\r
-    }\r
-\r
-    return Status;\r
-}\r
-\r
-FORCEINLINE\r
-NTSTATUS\r
-NTAPI\r
-RtlStringExValidateDestA(IN OUT PCHAR *Destination,\r
-                         IN OUT PSIZE_T DestinationLength,\r
-                         OUT PSIZE_T ReturnLength OPTIONAL,\r
-                         IN SIZE_T MaxLength,\r
-                         IN DWORD Flags)\r
-{\r
-    ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);\r
-    return RtlStringValidateDestA(*Destination,\r
-                                  *DestinationLength,\r
-                                  ReturnLength,\r
-                                  MaxLength);\r
-}\r
-\r
-FORCEINLINE\r
-NTSTATUS\r
-NTAPI\r
-RtlStringExValidateSrcA(IN OUT PCCHAR *Source OPTIONAL,\r
-                        IN OUT PSIZE_T ReturnLength OPTIONAL,\r
-                        IN SIZE_T MaxLength,\r
-                        IN DWORD Flags)\r
-{\r
-    NTSTATUS Status = STATUS_SUCCESS;\r
-    ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);\r
-\r
-    if ((ReturnLength) && (*ReturnLength >= MaxLength))\r
-    {\r
-        Status = STATUS_INVALID_PARAMETER;\r
-    }\r
-\r
-    return Status;\r
-}\r
-\r
-FORCEINLINE\r
-NTSTATUS\r
-NTAPI\r
-RtlStringVPrintfWorkerA(OUT PCHAR Destination,\r
-                        IN SIZE_T Length,\r
-                        OUT PSIZE_T NewLength OPTIONAL,\r
-                        IN PCCHAR Format,\r
-                        IN va_list argList)\r
-{\r
-    NTSTATUS Status = STATUS_SUCCESS;\r
-    ULONG Return;\r
-    SIZE_T MaxLength, LocalNewLength = 0;\r
-\r
-    MaxLength = Length - 1;\r
-\r
-    Return = _vsnprintf(Destination, MaxLength, Format, argList);\r
-    if ((Return < 0) || (Return > MaxLength))\r
-    {\r
-        Destination += MaxLength;\r
-        *Destination = ANSI_NULL;\r
-\r
-        LocalNewLength = MaxLength;\r
-\r
-        Status = STATUS_BUFFER_OVERFLOW;\r
-    }\r
-    else if (Return == MaxLength)\r
-    {\r
-        Destination += MaxLength;\r
-        *Destination = ANSI_NULL;\r
-\r
-        LocalNewLength = MaxLength;\r
-    }\r
-    else\r
-    {\r
-        LocalNewLength = Return;\r
-    }\r
-\r
-    if (NewLength) *NewLength = LocalNewLength;\r
-    return Status;\r
-}\r
-\r
-FORCEINLINE\r
-NTSTATUS\r
-NTAPI\r
-RtlStringCopyWorkerA(OUT PCHAR Destination,\r
-                     IN SIZE_T Length,\r
-                     OUT PSIZE_T NewLength OPTIONAL,\r
-                     IN PCCHAR Source,\r
-                     IN SIZE_T CopyLength)\r
-{\r
-    NTSTATUS Status = STATUS_SUCCESS;\r
-    SIZE_T LocalNewLength = 0;\r
-\r
-    while ((Length) && (CopyLength) && (*Source != ANSI_NULL))\r
-    {\r
-        *Destination++ = *Source++;\r
-        Length--;\r
-        CopyLength--;\r
-\r
-        LocalNewLength++;\r
-    }\r
-\r
-    if (!Length)\r
-    {\r
-        Destination--;\r
-        LocalNewLength--;\r
-\r
-        Status = STATUS_BUFFER_OVERFLOW;\r
-    }\r
-\r
-    *Destination = ANSI_NULL;\r
-\r
-    if (NewLength) *NewLength = LocalNewLength;\r
-    return Status;\r
-}\r
-\r
-/* PUBLIC FUNCTIONS **********************************************************/\r
-\r
-FORCEINLINE\r
-NTSTATUS\r
-NTAPI\r
-RtlStringCbPrintfA(OUT PCHAR Destination,\r
-                   IN SIZE_T Length,\r
-                   IN PCHAR Format,\r
-                   ...)\r
-{\r
-    NTSTATUS Status;\r
-    SIZE_T CharLength = Length / sizeof(CHAR);\r
-    va_list argList;\r
-\r
-    Status = RtlStringValidateDestA(Destination,\r
-                                    CharLength,\r
-                                    NULL,\r
-                                    NTSTRSAFE_MAX_CCH);\r
-    if (NT_SUCCESS(Status))\r
-    {\r
-        va_start(argList, Format);\r
-        Status = RtlStringVPrintfWorkerA(Destination,\r
-                                         CharLength,\r
-                                         NULL,\r
-                                         Format,\r
-                                         argList);\r
-        va_end(argList);\r
-    }\r
-\r
-    return Status;\r
-}\r
-\r
-FORCEINLINE\r
-NTSTATUS\r
-NTAPI\r
-RtlStringCbPrintfExA(OUT PCHAR Destination,\r
-                     IN SIZE_T Length,\r
-                     OUT PCHAR *DestinationEnd OPTIONAL,\r
-                     OUT PSIZE_T RemainingSize OPTIONAL,\r
-                     IN DWORD Flags,\r
-                     IN PCCHAR Format,\r
-                     ...)\r
-{\r
-    NTSTATUS Status;\r
-    SIZE_T CharLength = Length / sizeof(CHAR), Remaining, LocalNewLength = 0;\r
-    PCHAR LocalDestinationEnd;\r
-    va_list argList;\r
-    ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);\r
-\r
-    Status = RtlStringExValidateDestA(&Destination,\r
-                                      &CharLength,\r
-                                      NULL,\r
-                                      NTSTRSAFE_MAX_CCH,\r
-                                      Flags);\r
-    if (NT_SUCCESS(Status))\r
-    {\r
-        LocalDestinationEnd = Destination;\r
-        Remaining = CharLength;\r
-\r
-        Status = RtlStringExValidateSrcA(&Format,\r
-                                         NULL,\r
-                                         NTSTRSAFE_MAX_CCH,\r
-                                         Flags);\r
-        if (NT_SUCCESS(Status))\r
-        {\r
-            if (!Length)\r
-            {\r
-                if (*Format != ANSI_NULL)\r
-                {\r
-                    if (!Destination)\r
-                    {\r
-                        Status = STATUS_INVALID_PARAMETER;\r
-                    }\r
-                    else\r
-                    {\r
-                        Status = STATUS_BUFFER_OVERFLOW;\r
-                    }\r
-                }\r
-            }\r
-            else\r
-            {\r
-                va_start(argList, Format);\r
-                Status = RtlStringVPrintfWorkerA(Destination,\r
-                                                 CharLength,\r
-                                                 &LocalNewLength,\r
-                                                 Format,\r
-                                                 argList);\r
-                va_end(argList);\r
-\r
-                LocalDestinationEnd = Destination + LocalNewLength;\r
-                Remaining = CharLength - LocalNewLength;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            if (Length) *Destination = ANSI_NULL;\r
-        }\r
-\r
-        if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW))\r
-        {\r
-            if (DestinationEnd) *DestinationEnd = LocalDestinationEnd;\r
-\r
-            if (RemainingSize)\r
-            {\r
-                *RemainingSize = (Remaining * sizeof(CHAR)) +\r
-                                 (Length % sizeof(CHAR));\r
-            }\r
-        }\r
-    }\r
-\r
-    return Status;\r
-}\r
-\r
-FORCEINLINE\r
-NTSTATUS\r
-NTAPI\r
-RtlStringCbCopyExA(OUT PCHAR Destination,\r
-                   IN SIZE_T Length,\r
-                   IN PCCHAR Source,\r
-                   OUT PCHAR *DestinationEnd OPTIONAL,\r
-                   OUT PSIZE_T RemainingSize OPTIONAL,\r
-                   IN DWORD Flags)\r
-{\r
-    NTSTATUS Status;\r
-    SIZE_T CharLength = Length / sizeof(CHAR), Copied = 0, Remaining;\r
-    PCHAR LocalDestinationEnd;\r
-    ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);\r
-\r
-    Status = RtlStringExValidateDestA(&Destination,\r
-                                      &Length,\r
-                                      NULL,\r
-                                      NTSTRSAFE_MAX_CCH,\r
-                                      Flags);\r
-    if (NT_SUCCESS(Status))\r
-    {\r
-        LocalDestinationEnd = Destination;\r
-        Remaining = CharLength;\r
-\r
-        Status = RtlStringExValidateSrcA(&Source,\r
-                                         NULL,\r
-                                         NTSTRSAFE_MAX_CCH,\r
-                                         Flags);\r
-        if (NT_SUCCESS(Status))\r
-        {\r
-            if (!CharLength)\r
-            {\r
-                if (*Source != ANSI_NULL)\r
-                {\r
-                    if (!Destination)\r
-                    {\r
-                        Status = STATUS_INVALID_PARAMETER;\r
-                    }\r
-                    else\r
-                    {\r
-                        Status = STATUS_BUFFER_OVERFLOW;\r
-                    }\r
-                }\r
-            }\r
-            else\r
-            {\r
-                Status = RtlStringCopyWorkerA(Destination,\r
-                                              CharLength,\r
-                                              &Copied,\r
-                                              Source,\r
-                                              NTSTRSAFE_MAX_LENGTH);\r
-\r
-                LocalDestinationEnd = Destination + Copied;\r
-                Remaining = CharLength - Copied;\r
-            }\r
-        }\r
-        else\r
-        {\r
-            if (CharLength) *Destination = ANSI_NULL;\r
-        }\r
-\r
-        if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW))\r
-        {\r
-            if (DestinationEnd) *DestinationEnd = LocalDestinationEnd;\r
-\r
-            if (RemainingSize)\r
-            {\r
-                *RemainingSize = (Remaining * sizeof(CHAR)) +\r
-                                 (Length % sizeof(CHAR));\r
-            }\r
-        }\r
-    }\r
-\r
-    return Status;\r
-}\r
-\r
-FORCEINLINE\r
-NTSTATUS\r
-NTAPI\r
-RtlStringCbCatExA(IN OUT PCHAR Destination,\r
-                  IN SIZE_T Length,\r
-                  IN PCCHAR Source,\r
-                  OUT PCHAR *DestinationEnd OPTIONAL,\r
-                  OUT PSIZE_T RemainingSize OPTIONAL,\r
-                  IN DWORD Flags)\r
-{\r
-    NTSTATUS Status;\r
-    SIZE_T CharLength = Length / sizeof(CHAR);\r
-    SIZE_T DestinationLength, Remaining, Copied = 0;\r
-    PCHAR LocalDestinationEnd;\r
-    ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);\r
-\r
-    Status = RtlStringExValidateDestA(&Destination,\r
-                                      &CharLength,\r
-                                      &DestinationLength,\r
-                                      NTSTRSAFE_MAX_CCH,\r
-                                      Flags);\r
-    if (NT_SUCCESS(Status))\r
-    {\r
-        LocalDestinationEnd = Destination + DestinationLength;\r
-        Remaining = CharLength - DestinationLength;\r
-\r
-        Status = RtlStringExValidateSrcA(&Source,\r
-                                         NULL,\r
-                                         NTSTRSAFE_MAX_CCH,\r
-                                         Flags);\r
-        if (NT_SUCCESS(Status))\r
-        {\r
-            if (Remaining <= 1)\r
-            {\r
-                if (*Source != ANSI_NULL)\r
-                {\r
-                    if (!Destination)\r
-                    {\r
-                        Status = STATUS_INVALID_PARAMETER;\r
-                    }\r
-                    else\r
-                    {\r
-                        Status = STATUS_BUFFER_OVERFLOW;\r
-                    }\r
-                }\r
-            }\r
-            else\r
-            {\r
-                Status = RtlStringCopyWorkerA(LocalDestinationEnd,\r
-                                              Remaining,\r
-                                              &Copied,\r
-                                              Source,\r
-                                              NTSTRSAFE_MAX_LENGTH);\r
-\r
-                LocalDestinationEnd = LocalDestinationEnd + Copied;\r
-                Remaining = Remaining - Copied;\r
-            }\r
-        }\r
-\r
-        if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW))\r
-        {\r
-            if (DestinationEnd) *DestinationEnd = LocalDestinationEnd;\r
-\r
-            if (RemainingSize)\r
-            {\r
-                *RemainingSize = (Remaining * sizeof(CHAR)) +\r
-                                 (Length % sizeof(CHAR));\r
-            }\r
-        }\r
-    }\r
-\r
-    return Status;\r
-}\r
-\r
-FORCEINLINE\r
-NTSTATUS\r
-NTAPI\r
-RtlStringCbCopyA(OUT PCHAR Destination,\r
-                 IN SIZE_T Length,\r
-                 IN PCCHAR Source)\r
-{\r
-    NTSTATUS Status;\r
-    SIZE_T CharLength = Length / sizeof(CHAR);\r
-\r
-    Status = RtlStringValidateDestA(Destination,\r
-                                    CharLength,\r
-                                    NULL,\r
-                                    NTSTRSAFE_MAX_CCH);\r
-    if (NT_SUCCESS(Status))\r
-    {\r
-        Status = RtlStringCopyWorkerA(Destination,\r
-                                      CharLength,\r
-                                      NULL,\r
-                                      Source,\r
-                                      NTSTRSAFE_MAX_LENGTH);\r
-    }\r
-\r
-    return Status;\r
-}\r
-\r
-#endif\r
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         This file is in the public domain.
+ * FILE:            include/ddk/ntstrsafe.h
+ * PURPOSE:         Safe String Library for NT Code (Native/Kernel)
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#ifndef _NTSTRSAFE_H_INCLUDED_
+#define _NTSTRSAFE_H_INCLUDED_
+
+//
+// Dependencies
+//
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+//
+// Maximum limits: allow overriding the maximum
+//
+#ifndef NTSTRSAFE_MAX_CCH
+#define NTSTRSAFE_MAX_CCH       2147483647
+#endif
+#define NTSTRSAFE_MAX_LENGTH    (NTSTRSAFE_MAX_CCH - 1)
+
+//
+// Typedefs
+//
+typedef unsigned long DWORD;
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+static __inline
+NTSTATUS
+NTAPI
+RtlStringLengthWorkerA(IN LPCSTR String,
+                       IN SIZE_T MaxLength,
+                       OUT PSIZE_T ReturnLength OPTIONAL)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    SIZE_T LocalMax = MaxLength;
+
+    while (MaxLength && (*String != ANSI_NULL))
+    {
+        String++;
+        MaxLength--;
+    }
+
+    if (!MaxLength) Status = STATUS_INVALID_PARAMETER;
+
+    if (ReturnLength)
+    {
+        if (NT_SUCCESS(Status))
+        {
+            *ReturnLength = LocalMax - MaxLength;
+        }
+        else
+        {
+            *ReturnLength = 0;
+        }
+    }
+
+    return Status;
+}
+
+static __inline
+NTSTATUS
+NTAPI
+RtlStringValidateDestA(IN LPSTR Destination,
+                       IN SIZE_T Length,
+                       OUT PSIZE_T ReturnLength OPTIONAL,
+                       IN SIZE_T MaxLength)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    if (!(Length) || (Length > MaxLength)) Status = STATUS_INVALID_PARAMETER;
+
+    if (ReturnLength)
+    {
+        if (NT_SUCCESS(Status))
+        {
+            Status = RtlStringLengthWorkerA(Destination,
+                                            Length,
+                                            ReturnLength);
+        }
+        else
+        {
+            *ReturnLength = 0;
+        }
+    }
+
+    return Status;
+}
+
+static __inline
+NTSTATUS
+NTAPI
+RtlStringExValidateDestA(IN OUT LPSTR *Destination,
+                         IN OUT PSIZE_T DestinationLength,
+                         OUT PSIZE_T ReturnLength OPTIONAL,
+                         IN SIZE_T MaxLength,
+                         IN DWORD Flags)
+{
+    ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);
+    return RtlStringValidateDestA(*Destination,
+                                  *DestinationLength,
+                                  ReturnLength,
+                                  MaxLength);
+}
+
+static __inline
+NTSTATUS
+NTAPI
+RtlStringExValidateSrcA(IN OUT LPCSTR *Source OPTIONAL,
+                        IN OUT PSIZE_T ReturnLength OPTIONAL,
+                        IN SIZE_T MaxLength,
+                        IN DWORD Flags)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);
+
+    if ((ReturnLength) && (*ReturnLength >= MaxLength))
+    {
+        Status = STATUS_INVALID_PARAMETER;
+    }
+
+    return Status;
+}
+
+static __inline
+NTSTATUS
+NTAPI
+RtlStringVPrintfWorkerA(OUT LPSTR Destination,
+                        IN SIZE_T Length,
+                        OUT PSIZE_T NewLength OPTIONAL,
+                        IN LPCSTR Format,
+                        IN va_list argList)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    LONG Return;
+    SIZE_T MaxLength, LocalNewLength = 0;
+
+    MaxLength = Length - 1;
+
+    Return = _vsnprintf(Destination, MaxLength, Format, argList);
+    if ((Return < 0) || ((SIZE_T)Return > MaxLength))
+    {
+        Destination += MaxLength;
+        *Destination = ANSI_NULL;
+
+        LocalNewLength = MaxLength;
+
+        Status = STATUS_BUFFER_OVERFLOW;
+    }
+    else if ((SIZE_T)Return == MaxLength)
+    {
+        Destination += MaxLength;
+        *Destination = ANSI_NULL;
+
+        LocalNewLength = MaxLength;
+    }
+    else
+    {
+        LocalNewLength = Return;
+    }
+
+    if (NewLength) *NewLength = LocalNewLength;
+    return Status;
+}
+
+static __inline
+NTSTATUS
+NTAPI
+RtlStringCopyWorkerA(OUT LPSTR Destination,
+                     IN SIZE_T Length,
+                     OUT PSIZE_T NewLength OPTIONAL,
+                     IN LPCSTR Source,
+                     IN SIZE_T CopyLength)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    SIZE_T LocalNewLength = 0;
+
+    while ((Length) && (CopyLength) && (*Source != ANSI_NULL))
+    {
+        *Destination++ = *Source++;
+        Length--;
+        CopyLength--;
+
+        LocalNewLength++;
+    }
+
+    if (!Length)
+    {
+        Destination--;
+        LocalNewLength--;
+
+        Status = STATUS_BUFFER_OVERFLOW;
+    }
+
+    *Destination = ANSI_NULL;
+
+    if (NewLength) *NewLength = LocalNewLength;
+    return Status;
+}
+
+/* PUBLIC FUNCTIONS **********************************************************/
+
+static __inline
+NTSTATUS
+NTAPI
+RtlStringCchCopyA(IN LPSTR Destination,
+                  IN SIZE_T cchDest,
+                  IN LPCSTR pszSrc)
+{
+    ASSERTMSG("RtlStringCchCopyA is UNIMPLEMENTED!\n", FALSE);
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+static __inline
+NTSTATUS
+RtlStringCbPrintfA(OUT LPSTR Destination,
+                   IN SIZE_T Length,
+                   IN LPCSTR Format,
+                   ...)
+{
+    NTSTATUS Status;
+    SIZE_T CharLength = Length / sizeof(CHAR);
+    va_list argList;
+
+    Status = RtlStringValidateDestA(Destination,
+                                    CharLength,
+                                    NULL,
+                                    NTSTRSAFE_MAX_CCH);
+    if (NT_SUCCESS(Status))
+    {
+        va_start(argList, Format);
+        Status = RtlStringVPrintfWorkerA(Destination,
+                                         CharLength,
+                                         NULL,
+                                         Format,
+                                         argList);
+        va_end(argList);
+    }
+
+    return Status;
+}
+
+static __inline
+NTSTATUS
+RtlStringCbPrintfExA(OUT LPSTR Destination,
+                     IN SIZE_T Length,
+                     OUT LPSTR *DestinationEnd OPTIONAL,
+                     OUT PSIZE_T RemainingSize OPTIONAL,
+                     IN DWORD Flags,
+                     IN LPCSTR Format,
+                     ...)
+{
+    NTSTATUS Status;
+    SIZE_T CharLength = Length / sizeof(CHAR), Remaining, LocalNewLength = 0;
+    PCHAR LocalDestinationEnd;
+    va_list argList;
+    ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);
+
+    Status = RtlStringExValidateDestA(&Destination,
+                                      &CharLength,
+                                      NULL,
+                                      NTSTRSAFE_MAX_CCH,
+                                      Flags);
+    if (NT_SUCCESS(Status))
+    {
+        LocalDestinationEnd = Destination;
+        Remaining = CharLength;
+
+        Status = RtlStringExValidateSrcA(&Format,
+                                         NULL,
+                                         NTSTRSAFE_MAX_CCH,
+                                         Flags);
+        if (NT_SUCCESS(Status))
+        {
+            if (!Length)
+            {
+                if (*Format != ANSI_NULL)
+                {
+                    if (!Destination)
+                    {
+                        Status = STATUS_INVALID_PARAMETER;
+                    }
+                    else
+                    {
+                        Status = STATUS_BUFFER_OVERFLOW;
+                    }
+                }
+            }
+            else
+            {
+                va_start(argList, Format);
+                Status = RtlStringVPrintfWorkerA(Destination,
+                                                 CharLength,
+                                                 &LocalNewLength,
+                                                 Format,
+                                                 argList);
+                va_end(argList);
+
+                LocalDestinationEnd = Destination + LocalNewLength;
+                Remaining = CharLength - LocalNewLength;
+            }
+        }
+        else
+        {
+            if (Length) *Destination = ANSI_NULL;
+        }
+
+        if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW))
+        {
+            if (DestinationEnd) *DestinationEnd = LocalDestinationEnd;
+
+            if (RemainingSize)
+            {
+                *RemainingSize = (Remaining * sizeof(CHAR)) +
+                                 (Length % sizeof(CHAR));
+            }
+        }
+    }
+
+    return Status;
+}
+
+static __inline
+NTSTATUS
+NTAPI
+RtlStringCbCopyExA(OUT LPSTR Destination,
+                   IN SIZE_T Length,
+                   IN LPCSTR Source,
+                   OUT LPSTR *DestinationEnd OPTIONAL,
+                   OUT PSIZE_T RemainingSize OPTIONAL,
+                   IN DWORD Flags)
+{
+    NTSTATUS Status;
+    SIZE_T CharLength = Length / sizeof(CHAR), Copied = 0, Remaining;
+    PCHAR LocalDestinationEnd;
+    ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);
+
+    Status = RtlStringExValidateDestA(&Destination,
+                                      &Length,
+                                      NULL,
+                                      NTSTRSAFE_MAX_CCH,
+                                      Flags);
+    if (NT_SUCCESS(Status))
+    {
+        LocalDestinationEnd = Destination;
+        Remaining = CharLength;
+
+        Status = RtlStringExValidateSrcA(&Source,
+                                         NULL,
+                                         NTSTRSAFE_MAX_CCH,
+                                         Flags);
+        if (NT_SUCCESS(Status))
+        {
+            if (!CharLength)
+            {
+                if (*Source != ANSI_NULL)
+                {
+                    if (!Destination)
+                    {
+                        Status = STATUS_INVALID_PARAMETER;
+                    }
+                    else
+                    {
+                        Status = STATUS_BUFFER_OVERFLOW;
+                    }
+                }
+            }
+            else
+            {
+                Status = RtlStringCopyWorkerA(Destination,
+                                              CharLength,
+                                              &Copied,
+                                              Source,
+                                              NTSTRSAFE_MAX_LENGTH);
+
+                LocalDestinationEnd = Destination + Copied;
+                Remaining = CharLength - Copied;
+            }
+        }
+        else
+        {
+            if (CharLength) *Destination = ANSI_NULL;
+        }
+
+        if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW))
+        {
+            if (DestinationEnd) *DestinationEnd = LocalDestinationEnd;
+
+            if (RemainingSize)
+            {
+                *RemainingSize = (Remaining * sizeof(CHAR)) +
+                                 (Length % sizeof(CHAR));
+            }
+        }
+    }
+
+    return Status;
+}
+
+static __inline
+NTSTATUS
+RtlStringCbPrintfW(
+    LPWSTR pszDest,
+    IN size_t cbDest,
+    IN LPCWSTR pszFormat,
+    ...)
+{
+    ASSERTMSG("RtlStringCbPrintfW is UNIMPLEMENTED!\n", FALSE);
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+static __inline
+NTSTATUS
+NTAPI
+RtlStringCbCatExA(IN OUT LPSTR Destination,
+                  IN SIZE_T Length,
+                  IN LPCSTR Source,
+                  OUT LPSTR *DestinationEnd OPTIONAL,
+                  OUT PSIZE_T RemainingSize OPTIONAL,
+                  IN DWORD Flags)
+{
+    NTSTATUS Status;
+    SIZE_T CharLength = Length / sizeof(CHAR);
+    SIZE_T DestinationLength, Remaining, Copied = 0;
+    PCHAR LocalDestinationEnd;
+    ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);
+
+    Status = RtlStringExValidateDestA(&Destination,
+                                      &CharLength,
+                                      &DestinationLength,
+                                      NTSTRSAFE_MAX_CCH,
+                                      Flags);
+    if (NT_SUCCESS(Status))
+    {
+        LocalDestinationEnd = Destination + DestinationLength;
+        Remaining = CharLength - DestinationLength;
+
+        Status = RtlStringExValidateSrcA(&Source,
+                                         NULL,
+                                         NTSTRSAFE_MAX_CCH,
+                                         Flags);
+        if (NT_SUCCESS(Status))
+        {
+            if (Remaining <= 1)
+            {
+                if (*Source != ANSI_NULL)
+                {
+                    if (!Destination)
+                    {
+                        Status = STATUS_INVALID_PARAMETER;
+                    }
+                    else
+                    {
+                        Status = STATUS_BUFFER_OVERFLOW;
+                    }
+                }
+            }
+            else
+            {
+                Status = RtlStringCopyWorkerA(LocalDestinationEnd,
+                                              Remaining,
+                                              &Copied,
+                                              Source,
+                                              NTSTRSAFE_MAX_LENGTH);
+
+                LocalDestinationEnd = LocalDestinationEnd + Copied;
+                Remaining = Remaining - Copied;
+            }
+        }
+
+        if ((NT_SUCCESS(Status)) || (Status == STATUS_BUFFER_OVERFLOW))
+        {
+            if (DestinationEnd) *DestinationEnd = LocalDestinationEnd;
+
+            if (RemainingSize)
+            {
+                *RemainingSize = (Remaining * sizeof(CHAR)) +
+                                 (Length % sizeof(CHAR));
+            }
+        }
+    }
+
+    return Status;
+}
+
+static __inline
+NTSTATUS
+NTAPI
+RtlStringCbCopyA(OUT LPSTR Destination,
+                 IN SIZE_T Length,
+                 IN LPCSTR Source)
+{
+    NTSTATUS Status;
+    SIZE_T CharLength = Length / sizeof(CHAR);
+
+    Status = RtlStringValidateDestA(Destination,
+                                    CharLength,
+                                    NULL,
+                                    NTSTRSAFE_MAX_CCH);
+    if (NT_SUCCESS(Status))
+    {
+        Status = RtlStringCopyWorkerA(Destination,
+                                      CharLength,
+                                      NULL,
+                                      Source,
+                                      NTSTRSAFE_MAX_LENGTH);
+    }
+
+    return Status;
+}
+
+#endif /* _NTSTRSAFE_H_INCLUDED_ */