[DDK]
[reactos.git] / reactos / include / ddk / ntstrsafe.h
index e7a2653..055d3b3 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * PROJECT:         ReactOS Kernel
- * LICENSE:         GPL - See COPYING in the top level directory
+ * 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)
@@ -17,6 +17,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
+#include <windef.h> /* we need DWORD */
 
 //
 // Maximum limits: allow overriding the maximum
 #endif
 #define NTSTRSAFE_MAX_LENGTH    (NTSTRSAFE_MAX_CCH - 1)
 
-//
-// Typedefs
-//
-typedef unsigned long DWORD;
-
 /* PRIVATE FUNCTIONS *********************************************************/
 
-__inline
+static __inline
 NTSTATUS
 NTAPI
-RtlStringLengthWorkerA(IN PCHAR String,
+RtlStringLengthWorkerA(IN LPCSTR String,
                        IN SIZE_T MaxLength,
                        OUT PSIZE_T ReturnLength OPTIONAL)
 {
@@ -66,10 +62,43 @@ RtlStringLengthWorkerA(IN PCHAR String,
     return Status;
 }
 
-__inline
+static __inline
 NTSTATUS
 NTAPI
-RtlStringValidateDestA(IN PCHAR Destination,
+RtlStringLengthWorkerW(IN LPCWSTR String,
+                       IN SIZE_T MaxLength,
+                       OUT PSIZE_T ReturnLength OPTIONAL)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    SIZE_T LocalMax = MaxLength;
+
+    while (MaxLength && (*String != UNICODE_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)
@@ -95,10 +124,39 @@ RtlStringValidateDestA(IN PCHAR Destination,
     return Status;
 }
 
-__inline
+static __inline
+NTSTATUS
+NTAPI
+RtlStringValidateDestW(IN LPWSTR 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 = RtlStringLengthWorkerW(Destination,
+                                            Length,
+                                            ReturnLength);
+        }
+        else
+        {
+            *ReturnLength = 0;
+        }
+    }
+
+    return Status;
+}
+
+static __inline
 NTSTATUS
 NTAPI
-RtlStringExValidateDestA(IN OUT PCHAR *Destination,
+RtlStringExValidateDestA(IN OUT LPSTR *Destination,
                          IN OUT PSIZE_T DestinationLength,
                          OUT PSIZE_T ReturnLength OPTIONAL,
                          IN SIZE_T MaxLength,
@@ -111,10 +169,26 @@ RtlStringExValidateDestA(IN OUT PCHAR *Destination,
                                   MaxLength);
 }
 
-__inline
+static __inline
 NTSTATUS
 NTAPI
-RtlStringExValidateSrcA(IN OUT PCCHAR *Source OPTIONAL,
+RtlStringExValidateDestW(IN OUT LPWSTR *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 RtlStringValidateDestW(*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)
@@ -130,13 +204,32 @@ RtlStringExValidateSrcA(IN OUT PCCHAR *Source OPTIONAL,
     return Status;
 }
 
-__inline
+static __inline
 NTSTATUS
 NTAPI
-RtlStringVPrintfWorkerA(OUT PCHAR Destination,
+RtlStringExValidateSrcW(IN OUT LPCWSTR *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 PCCHAR Format,
+                        IN LPCSTR Format,
                         IN va_list argList)
 {
     NTSTATUS Status = STATUS_SUCCESS;
@@ -171,13 +264,13 @@ RtlStringVPrintfWorkerA(OUT PCHAR Destination,
     return Status;
 }
 
-__inline
+static __inline
 NTSTATUS
 NTAPI
-RtlStringCopyWorkerA(OUT PCHAR Destination,
+RtlStringCopyWorkerA(OUT LPSTR Destination,
                      IN SIZE_T Length,
                      OUT PSIZE_T NewLength OPTIONAL,
-                     IN PCCHAR Source,
+                     IN LPCSTR Source,
                      IN SIZE_T CopyLength)
 {
     NTSTATUS Status = STATUS_SUCCESS;
@@ -206,25 +299,70 @@ RtlStringCopyWorkerA(OUT PCHAR Destination,
     return Status;
 }
 
+static __inline
+NTSTATUS
+NTAPI
+RtlStringCopyWorkerW(OUT LPWSTR Destination,
+                     IN SIZE_T Length,
+                     OUT PSIZE_T NewLength OPTIONAL,
+                     IN LPCWSTR Source,
+                     IN SIZE_T CopyLength)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    SIZE_T LocalNewLength = 0;
+
+    while ((Length) && (CopyLength) && (*Source != UNICODE_NULL))
+    {
+        *Destination++ = *Source++;
+        Length--;
+        CopyLength--;
+
+        LocalNewLength++;
+    }
+
+    if (!Length)
+    {
+        Destination--;
+        LocalNewLength--;
+
+        Status = STATUS_BUFFER_OVERFLOW;
+    }
+
+    *Destination = UNICODE_NULL;
+
+    if (NewLength) *NewLength = LocalNewLength;
+    return Status;
+}
+
 /* PUBLIC FUNCTIONS **********************************************************/
 
-__inline
+static __inline
 NTSTATUS
 NTAPI
-RtlStringCchCopyA(IN PCHAR Destination,
+RtlStringCchCopyA(IN LPSTR Destination,
                   IN SIZE_T cchDest,
-                  IN PCCHAR pszSrc)
+                  IN LPCSTR pszSrc)
 {
     ASSERTMSG("RtlStringCchCopyA is UNIMPLEMENTED!\n", FALSE);
     return STATUS_NOT_IMPLEMENTED;
 }
 
-__inline
+static __inline
 NTSTATUS
 NTAPI
-RtlStringCbPrintfA(OUT PCHAR Destination,
+RtlStringCchCopyW(IN LPWSTR Destination,
+                  IN SIZE_T cchDest,
+                  IN LPCWSTR pszSrc)
+{
+    ASSERTMSG("RtlStringCchCopyA is UNIMPLEMENTED!\n", FALSE);
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+static __inline
+NTSTATUS
+RtlStringCbPrintfA(OUT LPSTR Destination,
                    IN SIZE_T Length,
-                   IN PCHAR Format,
+                   IN LPCSTR Format,
                    ...)
 {
     NTSTATUS Status;
@@ -249,15 +387,14 @@ RtlStringCbPrintfA(OUT PCHAR Destination,
     return Status;
 }
 
-__inline
+static __inline
 NTSTATUS
-NTAPI
-RtlStringCbPrintfExA(OUT PCHAR Destination,
+RtlStringCbPrintfExA(OUT LPSTR Destination,
                      IN SIZE_T Length,
-                     OUT PCHAR *DestinationEnd OPTIONAL,
+                     OUT LPSTR *DestinationEnd OPTIONAL,
                      OUT PSIZE_T RemainingSize OPTIONAL,
                      IN DWORD Flags,
-                     IN PCCHAR Format,
+                     IN LPCSTR Format,
                      ...)
 {
     NTSTATUS Status;
@@ -330,13 +467,13 @@ RtlStringCbPrintfExA(OUT PCHAR Destination,
     return Status;
 }
 
-__inline
+static __inline
 NTSTATUS
 NTAPI
-RtlStringCbCopyExA(OUT PCHAR Destination,
+RtlStringCbCopyExA(OUT LPSTR Destination,
                    IN SIZE_T Length,
-                   IN PCCHAR Source,
-                   OUT PCHAR *DestinationEnd OPTIONAL,
+                   IN LPCSTR Source,
+                   OUT LPSTR *DestinationEnd OPTIONAL,
                    OUT PSIZE_T RemainingSize OPTIONAL,
                    IN DWORD Flags)
 {
@@ -407,9 +544,8 @@ RtlStringCbCopyExA(OUT PCHAR Destination,
     return Status;
 }
 
-__inline
+static __inline
 NTSTATUS
-NTAPI
 RtlStringCbPrintfW(
     LPWSTR pszDest,
     IN size_t cbDest,
@@ -420,13 +556,13 @@ RtlStringCbPrintfW(
     return STATUS_NOT_IMPLEMENTED;
 }
 
-__inline
+static __inline
 NTSTATUS
 NTAPI
-RtlStringCbCatExA(IN OUT PCHAR Destination,
+RtlStringCbCatExA(IN OUT LPSTR Destination,
                   IN SIZE_T Length,
-                  IN PCCHAR Source,
-                  OUT PCHAR *DestinationEnd OPTIONAL,
+                  IN LPCSTR Source,
+                  OUT LPSTR *DestinationEnd OPTIONAL,
                   OUT PSIZE_T RemainingSize OPTIONAL,
                   IN DWORD Flags)
 {
@@ -494,12 +630,86 @@ RtlStringCbCatExA(IN OUT PCHAR Destination,
     return Status;
 }
 
-__inline
+static __inline
 NTSTATUS
 NTAPI
-RtlStringCbCopyA(OUT PCHAR Destination,
+RtlStringCbCatExW(IN OUT LPWSTR Destination,
+                  IN SIZE_T Length,
+                  IN LPCWSTR Source,
+                  OUT LPWSTR *DestinationEnd OPTIONAL,
+                  OUT PSIZE_T RemainingSize OPTIONAL,
+                  IN DWORD Flags)
+{
+    NTSTATUS Status;
+    SIZE_T CharLength = Length / sizeof(WCHAR);
+    SIZE_T DestinationLength, Remaining, Copied = 0;
+    PWCHAR LocalDestinationEnd;
+    ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);
+
+    Status = RtlStringExValidateDestW(&Destination,
+                                      &CharLength,
+                                      &DestinationLength,
+                                      NTSTRSAFE_MAX_CCH,
+                                      Flags);
+    if (NT_SUCCESS(Status))
+    {
+        LocalDestinationEnd = Destination + DestinationLength;
+        Remaining = CharLength - DestinationLength;
+
+        Status = RtlStringExValidateSrcW(&Source,
+                                         NULL,
+                                         NTSTRSAFE_MAX_CCH,
+                                         Flags);
+        if (NT_SUCCESS(Status))
+        {
+            if (Remaining <= 1)
+            {
+                if (*Source != UNICODE_NULL)
+                {
+                    if (!Destination)
+                    {
+                        Status = STATUS_INVALID_PARAMETER;
+                    }
+                    else
+                    {
+                        Status = STATUS_BUFFER_OVERFLOW;
+                    }
+                }
+            }
+            else
+            {
+                Status = RtlStringCopyWorkerW(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(WCHAR)) +
+                                 (Length % sizeof(WCHAR));
+            }
+        }
+    }
+
+    return Status;
+}
+
+static __inline
+NTSTATUS
+NTAPI
+RtlStringCbCopyA(OUT LPSTR Destination,
                  IN SIZE_T Length,
-                 IN PCCHAR Source)
+                 IN LPCSTR Source)
 {
     NTSTATUS Status;
     SIZE_T CharLength = Length / sizeof(CHAR);
@@ -520,4 +730,30 @@ RtlStringCbCopyA(OUT PCHAR Destination,
     return Status;
 }
 
-#endif
+static __inline
+NTSTATUS
+NTAPI
+RtlStringCbCopyW(OUT LPWSTR Destination,
+                 IN SIZE_T Length,
+                 IN LPCWSTR Source)
+{
+    NTSTATUS Status;
+    SIZE_T CharLength = Length / sizeof(WCHAR);
+
+    Status = RtlStringValidateDestW(Destination,
+                                    CharLength,
+                                    NULL,
+                                    NTSTRSAFE_MAX_CCH);
+    if (NT_SUCCESS(Status))
+    {
+        Status = RtlStringCopyWorkerW(Destination,
+                                      CharLength,
+                                      NULL,
+                                      Source,
+                                      NTSTRSAFE_MAX_LENGTH);
+    }
+
+    return Status;
+}
+
+#endif /* _NTSTRSAFE_H_INCLUDED_ */