2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: include/ddk/ntstrsafe.h
5 * PURPOSE: Safe String Library for NT Code (Native/Kernel)
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
11 #ifndef _NTSTRSAFE_H_INCLUDED_
12 #define _NTSTRSAFE_H_INCLUDED_
22 // Maximum limits: allow overriding the maximum
24 #ifndef NTSTRSAFE_MAX_CCH
25 #define NTSTRSAFE_MAX_CCH 2147483647
27 #define NTSTRSAFE_MAX_LENGTH (NTSTRSAFE_MAX_CCH - 1)
32 typedef unsigned long DWORD
;
35 #define UNIMPLEMENTED DbgPrint("WARNING: %s at %s:%d is UNIMPLEMENTED!\n",__FUNCTION__,__FILE__,__LINE__);
38 /* PRIVATE FUNCTIONS *********************************************************/
43 RtlStringLengthWorkerA(IN PCHAR String
,
45 OUT PSIZE_T ReturnLength OPTIONAL
)
47 NTSTATUS Status
= STATUS_SUCCESS
;
48 SIZE_T LocalMax
= MaxLength
;
50 while (MaxLength
&& (*String
!= ANSI_NULL
))
56 if (!MaxLength
) Status
= STATUS_INVALID_PARAMETER
;
60 if (NT_SUCCESS(Status
))
62 *ReturnLength
= LocalMax
- MaxLength
;
76 RtlStringValidateDestA(IN PCHAR Destination
,
78 OUT PSIZE_T ReturnLength OPTIONAL
,
81 NTSTATUS Status
= STATUS_SUCCESS
;
83 if (!(Length
) || (Length
> MaxLength
)) Status
= STATUS_INVALID_PARAMETER
;
87 if (NT_SUCCESS(Status
))
89 Status
= RtlStringLengthWorkerA(Destination
,
105 RtlStringExValidateDestA(IN OUT PCHAR
*Destination
,
106 IN OUT PSIZE_T DestinationLength
,
107 OUT PSIZE_T ReturnLength OPTIONAL
,
111 //ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);
112 return RtlStringValidateDestA(*Destination
,
121 RtlStringExValidateSrcA(IN OUT PCCHAR
*Source OPTIONAL
,
122 IN OUT PSIZE_T ReturnLength OPTIONAL
,
126 NTSTATUS Status
= STATUS_SUCCESS
;
127 //ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);
129 if ((ReturnLength
) && (*ReturnLength
>= MaxLength
))
131 Status
= STATUS_INVALID_PARAMETER
;
140 RtlStringVPrintfWorkerA(OUT PCHAR Destination
,
142 OUT PSIZE_T NewLength OPTIONAL
,
146 NTSTATUS Status
= STATUS_SUCCESS
;
148 SIZE_T MaxLength
, LocalNewLength
= 0;
150 MaxLength
= Length
- 1;
152 Return
= _vsnprintf(Destination
, MaxLength
, Format
, argList
);
153 if ((Return
< 0) || ((SIZE_T
)Return
> MaxLength
))
155 Destination
+= MaxLength
;
156 *Destination
= ANSI_NULL
;
158 LocalNewLength
= MaxLength
;
160 Status
= STATUS_BUFFER_OVERFLOW
;
162 else if ((SIZE_T
)Return
== MaxLength
)
164 Destination
+= MaxLength
;
165 *Destination
= ANSI_NULL
;
167 LocalNewLength
= MaxLength
;
171 LocalNewLength
= Return
;
174 if (NewLength
) *NewLength
= LocalNewLength
;
181 RtlStringCopyWorkerA(OUT PCHAR Destination
,
183 OUT PSIZE_T NewLength OPTIONAL
,
185 IN SIZE_T CopyLength
)
187 NTSTATUS Status
= STATUS_SUCCESS
;
188 SIZE_T LocalNewLength
= 0;
190 while ((Length
) && (CopyLength
) && (*Source
!= ANSI_NULL
))
192 *Destination
++ = *Source
++;
204 Status
= STATUS_BUFFER_OVERFLOW
;
207 *Destination
= ANSI_NULL
;
209 if (NewLength
) *NewLength
= LocalNewLength
;
213 /* PUBLIC FUNCTIONS **********************************************************/
217 RtlStringCbPrintfA(OUT PCHAR Destination
,
223 SIZE_T CharLength
= Length
/ sizeof(CHAR
);
226 Status
= RtlStringValidateDestA(Destination
,
230 if (NT_SUCCESS(Status
))
232 va_start(argList
, Format
);
233 Status
= RtlStringVPrintfWorkerA(Destination
,
246 RtlStringCbPrintfExA(OUT PCHAR Destination
,
248 OUT PCHAR
*DestinationEnd OPTIONAL
,
249 OUT PSIZE_T RemainingSize OPTIONAL
,
255 SIZE_T CharLength
= Length
/ sizeof(CHAR
), Remaining
, LocalNewLength
= 0;
256 PCHAR LocalDestinationEnd
;
258 //ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);
260 Status
= RtlStringExValidateDestA(&Destination
,
265 if (NT_SUCCESS(Status
))
267 LocalDestinationEnd
= Destination
;
268 Remaining
= CharLength
;
270 Status
= RtlStringExValidateSrcA(&Format
,
274 if (NT_SUCCESS(Status
))
278 if (*Format
!= ANSI_NULL
)
282 Status
= STATUS_INVALID_PARAMETER
;
286 Status
= STATUS_BUFFER_OVERFLOW
;
292 va_start(argList
, Format
);
293 Status
= RtlStringVPrintfWorkerA(Destination
,
300 LocalDestinationEnd
= Destination
+ LocalNewLength
;
301 Remaining
= CharLength
- LocalNewLength
;
306 if (Length
) *Destination
= ANSI_NULL
;
309 if ((NT_SUCCESS(Status
)) || (Status
== STATUS_BUFFER_OVERFLOW
))
311 if (DestinationEnd
) *DestinationEnd
= LocalDestinationEnd
;
315 *RemainingSize
= (Remaining
* sizeof(CHAR
)) +
316 (Length
% sizeof(CHAR
));
327 RtlStringCbCopyExA(OUT PCHAR Destination
,
330 OUT PCHAR
*DestinationEnd OPTIONAL
,
331 OUT PSIZE_T RemainingSize OPTIONAL
,
335 SIZE_T CharLength
= Length
/ sizeof(CHAR
), Copied
= 0, Remaining
;
336 PCHAR LocalDestinationEnd
;
337 //ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);
339 Status
= RtlStringExValidateDestA(&Destination
,
344 if (NT_SUCCESS(Status
))
346 LocalDestinationEnd
= Destination
;
347 Remaining
= CharLength
;
349 Status
= RtlStringExValidateSrcA(&Source
,
353 if (NT_SUCCESS(Status
))
357 if (*Source
!= ANSI_NULL
)
361 Status
= STATUS_INVALID_PARAMETER
;
365 Status
= STATUS_BUFFER_OVERFLOW
;
371 Status
= RtlStringCopyWorkerA(Destination
,
375 NTSTRSAFE_MAX_LENGTH
);
377 LocalDestinationEnd
= Destination
+ Copied
;
378 Remaining
= CharLength
- Copied
;
383 if (CharLength
) *Destination
= ANSI_NULL
;
386 if ((NT_SUCCESS(Status
)) || (Status
== STATUS_BUFFER_OVERFLOW
))
388 if (DestinationEnd
) *DestinationEnd
= LocalDestinationEnd
;
392 *RemainingSize
= (Remaining
* sizeof(CHAR
)) +
393 (Length
% sizeof(CHAR
));
407 IN LPCWSTR pszFormat
,
411 return STATUS_NOT_IMPLEMENTED
;
417 RtlStringCbCatExA(IN OUT PCHAR Destination
,
420 OUT PCHAR
*DestinationEnd OPTIONAL
,
421 OUT PSIZE_T RemainingSize OPTIONAL
,
425 SIZE_T CharLength
= Length
/ sizeof(CHAR
);
426 SIZE_T DestinationLength
, Remaining
, Copied
= 0;
427 PCHAR LocalDestinationEnd
;
428 //ASSERTMSG("We don't support Extended Flags yet!\n", Flags == 0);
430 Status
= RtlStringExValidateDestA(&Destination
,
435 if (NT_SUCCESS(Status
))
437 LocalDestinationEnd
= Destination
+ DestinationLength
;
438 Remaining
= CharLength
- DestinationLength
;
440 Status
= RtlStringExValidateSrcA(&Source
,
444 if (NT_SUCCESS(Status
))
448 if (*Source
!= ANSI_NULL
)
452 Status
= STATUS_INVALID_PARAMETER
;
456 Status
= STATUS_BUFFER_OVERFLOW
;
462 Status
= RtlStringCopyWorkerA(LocalDestinationEnd
,
466 NTSTRSAFE_MAX_LENGTH
);
468 LocalDestinationEnd
= LocalDestinationEnd
+ Copied
;
469 Remaining
= Remaining
- Copied
;
473 if ((NT_SUCCESS(Status
)) || (Status
== STATUS_BUFFER_OVERFLOW
))
475 if (DestinationEnd
) *DestinationEnd
= LocalDestinationEnd
;
479 *RemainingSize
= (Remaining
* sizeof(CHAR
)) +
480 (Length
% sizeof(CHAR
));
491 RtlStringCbCopyA(OUT PCHAR Destination
,
496 SIZE_T CharLength
= Length
/ sizeof(CHAR
);
498 Status
= RtlStringValidateDestA(Destination
,
502 if (NT_SUCCESS(Status
))
504 Status
= RtlStringCopyWorkerA(Destination
,
508 NTSTRSAFE_MAX_LENGTH
);