#ifndef _NTSTRSAFE_H_INCLUDED_
#ifndef NTSTRSAFE_LIB_IMPL
#ifndef _M_CEE_PURE
#ifndef NTSTRSAFE_NO_CB_FUNCTIONS
NTSTRSAFEDDI
RtlStringCbPrintfExA(
_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest,
_In_ size_t cbDest,
_Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PSTR* ppszDestEnd,
_Out_opt_ size_t* pcbRemaining,
_In_ DWORD dwFlags,
_In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,
...)
{
NTSTATUS status;
size_t cchDest = cbDest / sizeof(char);
status = RtlStringExValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags);
if (NT_SUCCESS(status))
{
NTSTRSAFE_PSTR pszDestEnd = pszDest;
size_t cchRemaining = cchDest;
status = RtlStringExValidateSrcA(&pszFormat, NULL, NTSTRSAFE_MAX_CCH, dwFlags);
if (NT_SUCCESS(status))
{
if (dwFlags & (~STRSAFE_VALID_FLAGS))
{
status = STATUS_INVALID_PARAMETER;
if (cchDest != 0)
{
*pszDest = '\0';
}
}
else if (cchDest == 0)
{
// only fail if there was actually a non-empty format string
if (*pszFormat != '\0')
{
if (pszDest == NULL)
{
status = STATUS_INVALID_PARAMETER;
}
else
{
status = STATUS_BUFFER_OVERFLOW;
}
}
else
{
// for consistency with other use in this case...
__analysis_assume_nullterminated(pszDest);
}
}
else
{
size_t cchNewDestLength = 0;
va_list argList;
va_start(argList, pszFormat);
status = RtlStringVPrintfWorkerA(pszDest,
cchDest,
&cchNewDestLength,
pszFormat,
argList);
va_end(argList);
pszDestEnd = pszDest + cchNewDestLength;
cchRemaining = cchDest - cchNewDestLength;
if (NT_SUCCESS(status) &&
(dwFlags & STRSAFE_FILL_BEHIND_NULL) &&
(cchRemaining > 1))
{
size_t cbRemaining;
// safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1
cbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char));
// handle the STRSAFE_FILL_BEHIND_NULL flag
RtlStringExHandleFillBehindNullA(pszDestEnd, cbRemaining, dwFlags);
}
}
}
else
{
if (cchDest != 0)
{
*pszDest = '\0';
}
}
if (!NT_SUCCESS(status) &&
(dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) &&
(cbDest != 0))
{
// handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags
RtlStringExHandleOtherFlagsA(pszDest,
cbDest,
0,
&pszDestEnd,
&cchRemaining,
dwFlags);
}
if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW))
{
if (ppszDestEnd)
{
*ppszDestEnd = pszDestEnd;
}
if (pcbRemaining)
{
// safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1
*pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char));
}
}
}
else if (cchDest > 0)
{
*pszDest = '\0';
}
return status;
}
View code on GitHub
No description available.