#ifndef _NTSTRSAFE_H_INCLUDED_
#ifndef NTSTRSAFE_LIB_IMPL
#ifndef NTSTRSAFE_NO_CB_FUNCTIONS
NTSTRSAFEDDI
RtlStringCbCatNExW(
_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest,
_In_ size_t cbDest,
_In_reads_bytes_(cbToAppend) STRSAFE_PCNZWCH pszSrc,
_In_ size_t cbToAppend,
_Outptr_opt_result_bytebuffer_(*pcbRemaining) NTSTRSAFE_PWSTR* ppszDestEnd,
_Out_opt_ size_t* pcbRemaining,
_In_ DWORD dwFlags)
{
NTSTATUS status;
size_t cchDest = cbDest / sizeof(wchar_t);
size_t cchDestLength;
status = RtlStringExValidateDestAndLengthW(pszDest,
cchDest,
&cchDestLength,
NTSTRSAFE_MAX_CCH,
dwFlags);
if (NT_SUCCESS(status))
{
NTSTRSAFE_PWSTR pszDestEnd = pszDest + cchDestLength;
size_t cchRemaining = cchDest - cchDestLength;
size_t cchToAppend = cbToAppend / sizeof(wchar_t);
status = RtlStringExValidateSrcW(&pszSrc, &cchToAppend, NTSTRSAFE_MAX_CCH, dwFlags);
if (NT_SUCCESS(status))
{
if (dwFlags & (~STRSAFE_VALID_FLAGS))
{
status = STATUS_INVALID_PARAMETER;
}
else if (cchRemaining <= 1)
{
// only fail if there was actually src data to append
if ((cchToAppend != 0) && (*pszSrc != L'\0'))
{
if (pszDest == NULL)
{
status = STATUS_INVALID_PARAMETER;
}
else
{
status = STATUS_BUFFER_OVERFLOW;
}
}
}
else
{
size_t cchCopied = 0;
status = RtlStringCopyWorkerW(pszDestEnd,
cchRemaining,
&cchCopied,
pszSrc,
cchToAppend);
pszDestEnd = pszDestEnd + cchCopied;
cchRemaining = cchRemaining - cchCopied;
if (NT_SUCCESS(status) && (dwFlags & STRSAFE_FILL_BEHIND_NULL))
{
size_t cbRemaining;
// safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2
cbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
// handle the STRSAFE_FILL_BEHIND_NULL flag
RtlStringExHandleFillBehindNullW(pszDestEnd, cbRemaining, dwFlags);
}
}
}
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
RtlStringExHandleOtherFlagsW(pszDest,
cbDest,
cchDestLength,
&pszDestEnd,
&cchRemaining,
dwFlags);
}
if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW))
{
if (ppszDestEnd)
{
*ppszDestEnd = pszDestEnd;
}
if (pcbRemaining)
{
// safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2
*pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t));
}
}
}
return status;
}
View code on GitHub
No description available.