Set svn:eol-style native on ntstrsafe.h

svn path=/trunk/; revision=39749
This commit is contained in:
Andrew Greenwood 2009-02-25 13:07:00 +00:00
parent 3268f920af
commit ef5347287b

View file

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