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
;
34 /* PRIVATE FUNCTIONS *********************************************************/
39 RtlStringLengthWorkerA(IN PCHAR 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 PCHAR 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 PCHAR
*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 PCCHAR
*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 PCHAR 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 PCHAR 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 PCHAR Destination
,
218 ASSERTMSG("RtlStringCchCopyA is UNIMPLEMENTED!\n", FALSE
);
219 return STATUS_NOT_IMPLEMENTED
;
225 RtlStringCbPrintfA(OUT PCHAR Destination
,
231 SIZE_T CharLength
= Length
/ sizeof(CHAR
);
234 Status
= RtlStringValidateDestA(Destination
,
238 if (NT_SUCCESS(Status
))
240 va_start(argList
, Format
);
241 Status
= RtlStringVPrintfWorkerA(Destination
,
255 RtlStringCbPrintfExA(OUT PCHAR Destination
,
257 OUT PCHAR
*DestinationEnd OPTIONAL
,
258 OUT PSIZE_T RemainingSize OPTIONAL
,
264 SIZE_T CharLength
= Length
/ sizeof(CHAR
), Remaining
, LocalNewLength
= 0;
265 PCHAR LocalDestinationEnd
;
267 ASSERTMSG("We don't support Extended Flags yet!\n", Flags
== 0);
269 Status
= RtlStringExValidateDestA(&Destination
,
274 if (NT_SUCCESS(Status
))
276 LocalDestinationEnd
= Destination
;
277 Remaining
= CharLength
;
279 Status
= RtlStringExValidateSrcA(&Format
,
283 if (NT_SUCCESS(Status
))
287 if (*Format
!= ANSI_NULL
)
291 Status
= STATUS_INVALID_PARAMETER
;
295 Status
= STATUS_BUFFER_OVERFLOW
;
301 va_start(argList
, Format
);
302 Status
= RtlStringVPrintfWorkerA(Destination
,
309 LocalDestinationEnd
= Destination
+ LocalNewLength
;
310 Remaining
= CharLength
- LocalNewLength
;
315 if (Length
) *Destination
= ANSI_NULL
;
318 if ((NT_SUCCESS(Status
)) || (Status
== STATUS_BUFFER_OVERFLOW
))
320 if (DestinationEnd
) *DestinationEnd
= LocalDestinationEnd
;
324 *RemainingSize
= (Remaining
* sizeof(CHAR
)) +
325 (Length
% sizeof(CHAR
));
336 RtlStringCbCopyExA(OUT PCHAR Destination
,
339 OUT PCHAR
*DestinationEnd OPTIONAL
,
340 OUT PSIZE_T RemainingSize OPTIONAL
,
344 SIZE_T CharLength
= Length
/ sizeof(CHAR
), Copied
= 0, Remaining
;
345 PCHAR LocalDestinationEnd
;
346 ASSERTMSG("We don't support Extended Flags yet!\n", Flags
== 0);
348 Status
= RtlStringExValidateDestA(&Destination
,
353 if (NT_SUCCESS(Status
))
355 LocalDestinationEnd
= Destination
;
356 Remaining
= CharLength
;
358 Status
= RtlStringExValidateSrcA(&Source
,
362 if (NT_SUCCESS(Status
))
366 if (*Source
!= ANSI_NULL
)
370 Status
= STATUS_INVALID_PARAMETER
;
374 Status
= STATUS_BUFFER_OVERFLOW
;
380 Status
= RtlStringCopyWorkerA(Destination
,
384 NTSTRSAFE_MAX_LENGTH
);
386 LocalDestinationEnd
= Destination
+ Copied
;
387 Remaining
= CharLength
- Copied
;
392 if (CharLength
) *Destination
= ANSI_NULL
;
395 if ((NT_SUCCESS(Status
)) || (Status
== STATUS_BUFFER_OVERFLOW
))
397 if (DestinationEnd
) *DestinationEnd
= LocalDestinationEnd
;
401 *RemainingSize
= (Remaining
* sizeof(CHAR
)) +
402 (Length
% sizeof(CHAR
));
416 IN LPCWSTR pszFormat
,
419 ASSERTMSG("RtlStringCbPrintfW is UNIMPLEMENTED!\n", FALSE
);
420 return STATUS_NOT_IMPLEMENTED
;
426 RtlStringCbCatExA(IN OUT PCHAR Destination
,
429 OUT PCHAR
*DestinationEnd OPTIONAL
,
430 OUT PSIZE_T RemainingSize OPTIONAL
,
434 SIZE_T CharLength
= Length
/ sizeof(CHAR
);
435 SIZE_T DestinationLength
, Remaining
, Copied
= 0;
436 PCHAR LocalDestinationEnd
;
437 ASSERTMSG("We don't support Extended Flags yet!\n", Flags
== 0);
439 Status
= RtlStringExValidateDestA(&Destination
,
444 if (NT_SUCCESS(Status
))
446 LocalDestinationEnd
= Destination
+ DestinationLength
;
447 Remaining
= CharLength
- DestinationLength
;
449 Status
= RtlStringExValidateSrcA(&Source
,
453 if (NT_SUCCESS(Status
))
457 if (*Source
!= ANSI_NULL
)
461 Status
= STATUS_INVALID_PARAMETER
;
465 Status
= STATUS_BUFFER_OVERFLOW
;
471 Status
= RtlStringCopyWorkerA(LocalDestinationEnd
,
475 NTSTRSAFE_MAX_LENGTH
);
477 LocalDestinationEnd
= LocalDestinationEnd
+ Copied
;
478 Remaining
= Remaining
- Copied
;
482 if ((NT_SUCCESS(Status
)) || (Status
== STATUS_BUFFER_OVERFLOW
))
484 if (DestinationEnd
) *DestinationEnd
= LocalDestinationEnd
;
488 *RemainingSize
= (Remaining
* sizeof(CHAR
)) +
489 (Length
% sizeof(CHAR
));
500 RtlStringCbCopyA(OUT PCHAR Destination
,
505 SIZE_T CharLength
= Length
/ sizeof(CHAR
);
507 Status
= RtlStringValidateDestA(Destination
,
511 if (NT_SUCCESS(Status
))
513 Status
= RtlStringCopyWorkerA(Destination
,
517 NTSTRSAFE_MAX_LENGTH
);