Merge pull request #2200 from RadWolfie/fix-RtlUnicodeStringToAnsiString

Fix RtlUnicodeStringToAnsiString bug
This commit is contained in:
PatrickvL 2021-04-20 10:44:41 +02:00 committed by GitHub
commit f0e99ba436
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 31 additions and 18 deletions

View File

@ -1677,10 +1677,9 @@ XBSYSAPI EXPORTNUM(307) xbox::ulong_xt FASTCALL xbox::RtlUlongByteSwap
RETURN(ret);
}
xbox::dword_xt WINAPI RtlUnicodeStringToAnsiSize(const xbox::UNICODE_STRING *str)
static xbox::dword_xt RtlUnicodeStringToAnsiSize(const xbox::UNICODE_STRING *str)
{
const wchar_t *src = (const wchar_t *)(str->Buffer);
xbox::dword_xt ret = wcsrtombs(nullptr, &src, (size_t)str->Length, nullptr);
xbox::dword_xt ret = str->Length / sizeof(xbox::ushort_xt);
return ret + 1; // +1 for the terminating null character
}
@ -1691,7 +1690,7 @@ XBSYSAPI EXPORTNUM(308) xbox::ntstatus_xt NTAPI xbox::RtlUnicodeStringToAnsiStri
(
IN OUT PSTRING DestinationString,
IN PUNICODE_STRING SourceString,
IN boolean_xt AllocateDestinationString
IN boolean_xt AllocateDestinationString
)
{
LOG_FUNC_BEGIN
@ -1700,28 +1699,42 @@ XBSYSAPI EXPORTNUM(308) xbox::ntstatus_xt NTAPI xbox::RtlUnicodeStringToAnsiStri
LOG_FUNC_ARG(AllocateDestinationString)
LOG_FUNC_END;
NTSTATUS ret = xbox::status_success;
dword_xt len = RtlUnicodeStringToAnsiSize(SourceString);
ntstatus_xt ret = xbox::status_success;
dword_xt AnsiMaxLength = RtlUnicodeStringToAnsiSize(SourceString);
DestinationString->Length = (USHORT)(len - 1);
if (AllocateDestinationString) {
DestinationString->MaximumLength = (USHORT)len;
if (!(DestinationString->Buffer = (PCHAR)ExAllocatePoolWithTag(len, 'grtS'))) {
return xbox::status_no_memory;
DestinationString->Length = (ushort_xt)(AnsiMaxLength - 1);
if (AllocateDestinationString) {
DestinationString->MaximumLength = (ushort_xt)AnsiMaxLength;
if (!(DestinationString->Buffer = (PCHAR)ExAllocatePoolWithTag(AnsiMaxLength, 'grtS'))) {
ret = xbox::status_no_memory;
goto forceReturn;
}
}
else if (DestinationString->MaximumLength < len) {
}
else if (DestinationString->MaximumLength < AnsiMaxLength) {
ret = xbox::status_buffer_overflow;
if (!DestinationString->MaximumLength) {
return xbox::status_buffer_overflow;
goto forceReturn;
}
DestinationString->Length = DestinationString->MaximumLength - 1;
ret = xbox::status_buffer_overflow;
}
}
RtlUnicodeToMultiByteN(DestinationString->Buffer, DestinationString->Length, NULL, (PWSTR)SourceString->Buffer, (ULONG)SourceString->Length);
DestinationString->Buffer[DestinationString->Length] = 0;
xbox::ulong_xt index = 0;
ntstatus_xt result = RtlUnicodeToMultiByteN(DestinationString->Buffer, DestinationString->Length, &index, (PWSTR)SourceString->Buffer, SourceString->Length);
if (nt_success(result)) {
DestinationString->Buffer[index] = 0;
}
else {
if (AllocateDestinationString) {
ExFreePool(DestinationString->Buffer);
DestinationString->Buffer = zeroptr;
}
ret = result;
}
forceReturn:
RETURN(ret);
}