Add most of RtlString***W functions based on ANSI versions.

svn path=/trunk/; revision=51130
This commit is contained in:
Rafal Harabien 2011-03-23 20:36:25 +00:00
parent 4732a3af3d
commit a3c683546c

View file

@ -17,6 +17,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdarg.h> #include <stdarg.h>
#include <windef.h> /* we need DWORD */
// //
// Maximum limits: allow overriding the maximum // Maximum limits: allow overriding the maximum
@ -26,11 +27,6 @@
#endif #endif
#define NTSTRSAFE_MAX_LENGTH (NTSTRSAFE_MAX_CCH - 1) #define NTSTRSAFE_MAX_LENGTH (NTSTRSAFE_MAX_CCH - 1)
//
// Typedefs
//
typedef unsigned long DWORD;
/* PRIVATE FUNCTIONS *********************************************************/ /* PRIVATE FUNCTIONS *********************************************************/
static __inline static __inline
@ -66,6 +62,39 @@ RtlStringLengthWorkerA(IN LPCSTR String,
return Status; return Status;
} }
static __inline
NTSTATUS
NTAPI
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 static __inline
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -95,6 +124,35 @@ RtlStringValidateDestA(IN LPSTR Destination,
return Status; return Status;
} }
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 static __inline
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -111,6 +169,22 @@ RtlStringExValidateDestA(IN OUT LPSTR *Destination,
MaxLength); MaxLength);
} }
static __inline
NTSTATUS
NTAPI
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 static __inline
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -130,6 +204,25 @@ RtlStringExValidateSrcA(IN OUT LPCSTR *Source OPTIONAL,
return Status; return Status;
} }
static __inline
NTSTATUS
NTAPI
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 static __inline
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -206,6 +299,41 @@ RtlStringCopyWorkerA(OUT LPSTR Destination,
return Status; 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 **********************************************************/ /* PUBLIC FUNCTIONS **********************************************************/
static __inline static __inline
@ -219,6 +347,17 @@ RtlStringCchCopyA(IN LPSTR Destination,
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
} }
static __inline
NTSTATUS
NTAPI
RtlStringCchCopyW(IN LPWSTR Destination,
IN SIZE_T cchDest,
IN LPCWSTR pszSrc)
{
ASSERTMSG("RtlStringCchCopyA is UNIMPLEMENTED!\n", FALSE);
return STATUS_NOT_IMPLEMENTED;
}
static __inline static __inline
NTSTATUS NTSTATUS
RtlStringCbPrintfA(OUT LPSTR Destination, RtlStringCbPrintfA(OUT LPSTR Destination,
@ -491,6 +630,80 @@ RtlStringCbCatExA(IN OUT LPSTR Destination,
return Status; return Status;
} }
static __inline
NTSTATUS
NTAPI
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 static __inline
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -517,4 +730,30 @@ RtlStringCbCopyA(OUT LPSTR Destination,
return Status; return Status;
} }
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_ */ #endif /* _NTSTRSAFE_H_INCLUDED_ */