2 * PROJECT: ReactOS Kernel
3 * LICENSE: This file is in the public domain.
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
;
34 /* PRIVATE FUNCTIONS *********************************************************/
39 RtlStringLengthWorkerA(IN LPCSTR String
,
41 OUT PSIZE_T ReturnLength OPTIONAL
)
43 NTSTATUS Status
= STATUS_SUCCESS
;
44 SIZE_T LocalMax
= MaxLength
;
46 while (MaxLength
&& (*String
!= ANSI_NULL
))
52 if (!MaxLength
) Status
= STATUS_INVALID_PARAMETER
;
56 if (NT_SUCCESS(Status
))
58 *ReturnLength
= LocalMax
- MaxLength
;
72 RtlStringValidateDestA(IN LPSTR Destination
,
74 OUT PSIZE_T ReturnLength OPTIONAL
,
77 NTSTATUS Status
= STATUS_SUCCESS
;
79 if (!(Length
) || (Length
> MaxLength
)) Status
= STATUS_INVALID_PARAMETER
;
83 if (NT_SUCCESS(Status
))
85 Status
= RtlStringLengthWorkerA(Destination
,
101 RtlStringExValidateDestA(IN OUT LPSTR
*Destination
,
102 IN OUT PSIZE_T DestinationLength
,
103 OUT PSIZE_T ReturnLength OPTIONAL
,
107 ASSERTMSG("We don't support Extended Flags yet!\n", Flags
== 0);
108 return RtlStringValidateDestA(*Destination
,
117 RtlStringExValidateSrcA(IN OUT LPCSTR
*Source OPTIONAL
,
118 IN OUT PSIZE_T ReturnLength OPTIONAL
,
122 NTSTATUS Status
= STATUS_SUCCESS
;
123 ASSERTMSG("We don't support Extended Flags yet!\n", Flags
== 0);
125 if ((ReturnLength
) && (*ReturnLength
>= MaxLength
))
127 Status
= STATUS_INVALID_PARAMETER
;
136 RtlStringVPrintfWorkerA(OUT LPSTR Destination
,
138 OUT PSIZE_T NewLength OPTIONAL
,
142 NTSTATUS Status
= STATUS_SUCCESS
;
144 SIZE_T MaxLength
, LocalNewLength
= 0;
146 MaxLength
= Length
- 1;
148 Return
= _vsnprintf(Destination
, MaxLength
, Format
, argList
);
149 if ((Return
< 0) || ((SIZE_T
)Return
> MaxLength
))
151 Destination
+= MaxLength
;
152 *Destination
= ANSI_NULL
;
154 LocalNewLength
= MaxLength
;
156 Status
= STATUS_BUFFER_OVERFLOW
;
158 else if ((SIZE_T
)Return
== MaxLength
)
160 Destination
+= MaxLength
;
161 *Destination
= ANSI_NULL
;
163 LocalNewLength
= MaxLength
;
167 LocalNewLength
= Return
;
170 if (NewLength
) *NewLength
= LocalNewLength
;
177 RtlStringCopyWorkerA(OUT LPSTR Destination
,
179 OUT PSIZE_T NewLength OPTIONAL
,
181 IN SIZE_T CopyLength
)
183 NTSTATUS Status
= STATUS_SUCCESS
;
184 SIZE_T LocalNewLength
= 0;
186 while ((Length
) && (CopyLength
) && (*Source
!= ANSI_NULL
))
188 *Destination
++ = *Source
++;
200 Status
= STATUS_BUFFER_OVERFLOW
;
203 *Destination
= ANSI_NULL
;
205 if (NewLength
) *NewLength
= LocalNewLength
;
209 /* PUBLIC FUNCTIONS **********************************************************/
214 RtlStringCchCopyA(IN LPSTR Destination
,
218 ASSERTMSG("RtlStringCchCopyA is UNIMPLEMENTED!\n", FALSE
);
219 return STATUS_NOT_IMPLEMENTED
;
224 RtlStringCbPrintfA(OUT LPSTR Destination
,
230 SIZE_T CharLength
= Length
/ sizeof(CHAR
);
233 Status
= RtlStringValidateDestA(Destination
,
237 if (NT_SUCCESS(Status
))
239 va_start(argList
, Format
);
240 Status
= RtlStringVPrintfWorkerA(Destination
,
253 RtlStringCbPrintfExA(OUT LPSTR Destination
,
255 OUT LPSTR
*DestinationEnd OPTIONAL
,
256 OUT PSIZE_T RemainingSize OPTIONAL
,
262 SIZE_T CharLength
= Length
/ sizeof(CHAR
), Remaining
, LocalNewLength
= 0;
263 PCHAR LocalDestinationEnd
;
265 ASSERTMSG("We don't support Extended Flags yet!\n", Flags
== 0);
267 Status
= RtlStringExValidateDestA(&Destination
,
272 if (NT_SUCCESS(Status
))
274 LocalDestinationEnd
= Destination
;
275 Remaining
= CharLength
;
277 Status
= RtlStringExValidateSrcA(&Format
,
281 if (NT_SUCCESS(Status
))
285 if (*Format
!= ANSI_NULL
)
289 Status
= STATUS_INVALID_PARAMETER
;
293 Status
= STATUS_BUFFER_OVERFLOW
;
299 va_start(argList
, Format
);
300 Status
= RtlStringVPrintfWorkerA(Destination
,
307 LocalDestinationEnd
= Destination
+ LocalNewLength
;
308 Remaining
= CharLength
- LocalNewLength
;
313 if (Length
) *Destination
= ANSI_NULL
;
316 if ((NT_SUCCESS(Status
)) || (Status
== STATUS_BUFFER_OVERFLOW
))
318 if (DestinationEnd
) *DestinationEnd
= LocalDestinationEnd
;
322 *RemainingSize
= (Remaining
* sizeof(CHAR
)) +
323 (Length
% sizeof(CHAR
));
334 RtlStringCbCopyExA(OUT LPSTR Destination
,
337 OUT LPSTR
*DestinationEnd OPTIONAL
,
338 OUT PSIZE_T RemainingSize OPTIONAL
,
342 SIZE_T CharLength
= Length
/ sizeof(CHAR
), Copied
= 0, Remaining
;
343 PCHAR LocalDestinationEnd
;
344 ASSERTMSG("We don't support Extended Flags yet!\n", Flags
== 0);
346 Status
= RtlStringExValidateDestA(&Destination
,
351 if (NT_SUCCESS(Status
))
353 LocalDestinationEnd
= Destination
;
354 Remaining
= CharLength
;
356 Status
= RtlStringExValidateSrcA(&Source
,
360 if (NT_SUCCESS(Status
))
364 if (*Source
!= ANSI_NULL
)
368 Status
= STATUS_INVALID_PARAMETER
;
372 Status
= STATUS_BUFFER_OVERFLOW
;
378 Status
= RtlStringCopyWorkerA(Destination
,
382 NTSTRSAFE_MAX_LENGTH
);
384 LocalDestinationEnd
= Destination
+ Copied
;
385 Remaining
= CharLength
- Copied
;
390 if (CharLength
) *Destination
= ANSI_NULL
;
393 if ((NT_SUCCESS(Status
)) || (Status
== STATUS_BUFFER_OVERFLOW
))
395 if (DestinationEnd
) *DestinationEnd
= LocalDestinationEnd
;
399 *RemainingSize
= (Remaining
* sizeof(CHAR
)) +
400 (Length
% sizeof(CHAR
));
413 IN LPCWSTR pszFormat
,
416 ASSERTMSG("RtlStringCbPrintfW is UNIMPLEMENTED!\n", FALSE
);
417 return STATUS_NOT_IMPLEMENTED
;
423 RtlStringCbCatExA(IN OUT LPSTR Destination
,
426 OUT LPSTR
*DestinationEnd OPTIONAL
,
427 OUT PSIZE_T RemainingSize OPTIONAL
,
431 SIZE_T CharLength
= Length
/ sizeof(CHAR
);
432 SIZE_T DestinationLength
, Remaining
, Copied
= 0;
433 PCHAR LocalDestinationEnd
;
434 ASSERTMSG("We don't support Extended Flags yet!\n", Flags
== 0);
436 Status
= RtlStringExValidateDestA(&Destination
,
441 if (NT_SUCCESS(Status
))
443 LocalDestinationEnd
= Destination
+ DestinationLength
;
444 Remaining
= CharLength
- DestinationLength
;
446 Status
= RtlStringExValidateSrcA(&Source
,
450 if (NT_SUCCESS(Status
))
454 if (*Source
!= ANSI_NULL
)
458 Status
= STATUS_INVALID_PARAMETER
;
462 Status
= STATUS_BUFFER_OVERFLOW
;
468 Status
= RtlStringCopyWorkerA(LocalDestinationEnd
,
472 NTSTRSAFE_MAX_LENGTH
);
474 LocalDestinationEnd
= LocalDestinationEnd
+ Copied
;
475 Remaining
= Remaining
- Copied
;
479 if ((NT_SUCCESS(Status
)) || (Status
== STATUS_BUFFER_OVERFLOW
))
481 if (DestinationEnd
) *DestinationEnd
= LocalDestinationEnd
;
485 *RemainingSize
= (Remaining
* sizeof(CHAR
)) +
486 (Length
% sizeof(CHAR
));
497 RtlStringCbCopyA(OUT LPSTR Destination
,
502 SIZE_T CharLength
= Length
/ sizeof(CHAR
);
504 Status
= RtlStringValidateDestA(Destination
,
508 if (NT_SUCCESS(Status
))
510 Status
= RtlStringCopyWorkerA(Destination
,
514 NTSTRSAFE_MAX_LENGTH
);
520 #endif /* _NTSTRSAFE_H_INCLUDED_ */