/*
* 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)
#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)
{
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)
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,
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)
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;
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;
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;
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;
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)
{
return Status;
}
-__inline
+static __inline
NTSTATUS
-NTAPI
RtlStringCbPrintfW(
LPWSTR pszDest,
IN size_t cbDest,
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)
{
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);
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_ */