As per your original question:
_snwprintf_s - Writes formatted data to a string. These are versions of snprintf, _snprintf, _snprintf_l, _snwprintf, _snwprintf_l with security enhancements as described in Security Features in the CRT.
RtlStringCchPrintfExW - The RtlStringCchPrintfExW and RtlStringCchPrintfExA functions create a character-counted text string, with formatting that is based on supplied formatting information.
Remarks
RtlStringCchPrintfExW and RtlStringCchPrintfExA should be used instead of the following functions:
- sprintf
- swprintf
- _snprintf
- _snwprintf
In drivers, I personally prefer to use functions like Rtl* (as the docs suggest). Unfortunately, I cannot show you the source code of this from Windows, but ReactOS is nice enough to show us a body:
NTSTRSAFEVAPI
RtlStringCchPrintfExW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest,_Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PWSTR *ppszDestEnd,
_Out_opt_ size_t *pcchRemaining, _In_ STRSAFE_DWORD dwFlags, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat, ...)
{
NTSTATUS Status;
size_t cbDest = cchDest * sizeof(wchar_t);
va_list argList;
if (cchDest > NTSTRSAFE_MAX_CCH)
{
if (cchDest > 0)
*pszDest = L'\0';
return STATUS_INVALID_PARAMETER;
}
va_start(argList, pszFormat);
Status = RtlStringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList);
va_end(argList);
return Status;
}
As you can see this takes advantage of the NTSTRSAFE. The function will use va_list and pass the work onto RtlStringVPrintfExWorkerW → RtlpStringVPrintfExWorkerW which does everything inside the kernel.
Using RtlStringCchPrintfExW is most definitely the “safe” and “better” way to go.