From a3c683546ccdd935f6461f0ecccafc8193073685 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Wed, 23 Mar 2011 20:36:25 +0000 Subject: [PATCH] [DDK] Add most of RtlString***W functions based on ANSI versions. svn path=/trunk/; revision=51130 --- reactos/include/ddk/ntstrsafe.h | 249 +++++++++++++++++++++++++++++++- 1 file changed, 244 insertions(+), 5 deletions(-) diff --git a/reactos/include/ddk/ntstrsafe.h b/reactos/include/ddk/ntstrsafe.h index c107a0da425..055d3b312d2 100644 --- a/reactos/include/ddk/ntstrsafe.h +++ b/reactos/include/ddk/ntstrsafe.h @@ -17,6 +17,7 @@ #include #include #include +#include /* we need DWORD */ // // Maximum limits: allow overriding the maximum @@ -26,11 +27,6 @@ #endif #define NTSTRSAFE_MAX_LENGTH (NTSTRSAFE_MAX_CCH - 1) -// -// Typedefs -// -typedef unsigned long DWORD; - /* PRIVATE FUNCTIONS *********************************************************/ static __inline @@ -66,6 +62,39 @@ RtlStringLengthWorkerA(IN LPCSTR String, 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 NTSTATUS NTAPI @@ -95,6 +124,35 @@ RtlStringValidateDestA(IN LPSTR Destination, 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 NTSTATUS NTAPI @@ -111,6 +169,22 @@ RtlStringExValidateDestA(IN OUT LPSTR *Destination, 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 NTSTATUS NTAPI @@ -130,6 +204,25 @@ RtlStringExValidateSrcA(IN OUT LPCSTR *Source OPTIONAL, 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 NTSTATUS NTAPI @@ -206,6 +299,41 @@ RtlStringCopyWorkerA(OUT LPSTR 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 **********************************************************/ static __inline @@ -219,6 +347,17 @@ RtlStringCchCopyA(IN LPSTR Destination, 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 NTSTATUS RtlStringCbPrintfA(OUT LPSTR Destination, @@ -491,6 +630,80 @@ RtlStringCbCatExA(IN OUT LPSTR Destination, 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 NTSTATUS NTAPI @@ -517,4 +730,30 @@ RtlStringCbCopyA(OUT LPSTR Destination, 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_ */ -- 2.17.1