关于RtlUnicodeStringToAnsiString的文件对于可能的失败是相当模糊的 - 模糊不清,我的意思是它没有说出任何关于它们的内容。
我不确定如何/是否处理不同的编码,或者如果我的理解是如此有缺陷以至于它甚至不会进入等式,但让我们假设输入是{ {3}}出于争论的缘故。
如果所有字符都在ASCII范围内,则没有问题,它们可能会被截断并丢失高位字节 - 前128个Unicode代码点是ASCII字符,UTF-16编码U + 0000到U + D7FF在数值上等于代码点。UTF-16 [1]
注意:[2]有一个WCHAR *缓冲区,UNICODE_STRING有一个CHAR *缓冲区,可能是预期的。
[跳过129-255和区域设置/代码页]
255以上的字符会怎样?有ANSI_STRING功能,因此可以安全地假设它不能转换为UTF-8。
RtlUnicodeToUTF8N之外的代码点(代理对和诸如此类的东西)怎么样?
我看到了一个类似下面代码的函数:
char *pTarget = reinterpret_cast<char*>(char_str);
const WCHAR *pSource = reinterpret_cast<const WCHAR*>(wchar_str);
for ( long i = 0; i < targetMaxSizeInBytes; i++ )
{
*pTarget = static_cast<char>(*pSource);
if (L'\0' == *pSource)
break;
pTarget++;
pSource++;
}
这会导致任何非ASCII字符出现问题,对吗?
更新
来自RbMm的答案:
的shell
我得到更多信息:
与 RtlUnicodeToMultiByteSize 类似, RtlUnicodeToMultiByteN 仅支持映射到系统启动时安装的当前系统ANSI代码页的预先组合的Unicode字符。
RtlUnicodeToMultiByteN有一个选项,如果转换中使用的默认字符无法在指定的代码页中表示,则会通知
lpUsedDefaultChar [out,optional]
指向标志的指针,该标志指示该函数是否在转换中使用了默认字符。如果源字符串中的一个或多个字符无法在指定的代码页中表示,则该标志设置为 TRUE 。否则,该标志设置为 FALSE 。此参数可以设置为 NULL 。
然而,似乎RtlUnicodeToMultiByteN,因此RtlUnicodeStringToAnsiString,似乎不支持当前代码页之外的字符?
我尝试了几个角色并且看似随机转换(见下文) - 更重要的是,我返回了 STATUS_SUCCESS 。
U+03A3 Σ -> 0n83 'S'
U+03A4 Τ -> 0n63 '?'
U+03A5 Υ -> 0n63 '?'
U+03A6 Φ -> 0n70 'F'
答案 0 :(得分:1)
RtlUnicodeStringToAnsiString
是RtlUnicodeToMultiByteN
例程
RtlUnicodeToMultiByteN 例程转换指定的Unicode 使用当前系统 ANSI将字符串转换为新的字符串 代码页(ACP)。翻译的字符串不一定来自a 多字节字符集。
所以此例程中的任何一个都与WideCharToMultiByte
具有 CP_ACP
也存在下一个例程:
RtlUnicodeStringToOemString
- shell RtlUnicodeToOemN
例程
RtlUnicodeToOemN 例程将给定的Unicode字符串转换为 OEM字符串,使用当前系统 OEM代码页。
因此,此例程与WideCharToMultiByte
的转化次数与 CP_OEMCP
UTF-8 转换存在RtlUnicodeToUTF8N
(将Unicode字符串转换为UTF-8字符串)和RtlUTF8ToUnicodeN
(将UTF-8字符串转换为Unicode字符串。)
对于自定义代码页,您可以使用未记录的api
NTSYSAPI
NTSTATUS
NTAPI
RtlCustomCPToUnicodeN(
_In_ PCPTABLEINFO CustomCP,
_Out_writes_bytes_to_(MaxBytesInUnicodeString, *BytesInUnicodeString) PWCH UnicodeString,
_In_ ULONG MaxBytesInUnicodeString,
_Out_opt_ PULONG BytesInUnicodeString,
_In_reads_bytes_(BytesInCustomCPString) PCH CustomCPString,
_In_ ULONG BytesInCustomCPString
);
这里是初始化CPTABLEINFO
的关键点,因此您可以使用任何 USHORT CodePage; 此处
答案 1 :(得分:0)
不确定这是否有帮助,但我之前使用WideCharToMultiByte转换为UTF-16(wchar_t *)和UTF-8(char *),并将CP_UTF8
作为代码页传递。
编辑:我刚刚注意到了内核标签。我引用的函数是用户模式(kernel32.dll),因此可能对内核模式代码没用。 :(