C++ 使用RtlUnicodeStringToAnsiString将UNICODE_字符串转换为ANSI_字符串

C++ 使用RtlUnicodeStringToAnsiString将UNICODE_字符串转换为ANSI_字符串,c++,unicode,kernel,driver,C++,Unicode,Kernel,Driver,关于它的文档对于可能的失败是相当模糊的——模糊的意思是它没有说任何关于它们的内容 我不太清楚它是如何处理不同的编码的,或者我的理解是否有缺陷,以至于它甚至没有进入等式,但让我们假设输入是为了参数 如果所有字符都在ASCII范围内,则没有问题,它们可能会被截断并丢失高阶字节-前128个Unicode代码点是ASCII字符,UTF-16将U+0000编码为U+D7FF,在数字上等于代码点 注意:有一个WCHAR*缓冲区和一个CHAR*缓冲区,这是可以预期的 [跳过129-255和地区/代码页] 25

关于它的文档对于可能的失败是相当模糊的——模糊的意思是它没有说任何关于它们的内容

我不太清楚它是如何处理不同的编码的,或者我的理解是否有缺陷,以至于它甚至没有进入等式,但让我们假设输入是为了参数

如果所有字符都在ASCII范围内,则没有问题,它们可能会被截断并丢失高阶字节-前128个Unicode代码点是ASCII字符,UTF-16将U+0000编码为U+D7FF,在数字上等于代码点

注意:有一个WCHAR*缓冲区和一个CHAR*缓冲区,这是可以预期的

[跳过129-255和地区/代码页]

255以上的字符会发生什么情况?有一个函数,所以可以安全地假设它没有转换为UTF-8

外部的代码点(代理项对等等)怎么样

我看到了一个函数,它执行如下代码:

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++;
}

不确定这是否有用,但我以前使用过从UTF-16(wchar\u t*)和UTF-8(char*)转换,将
CP\u UTF8
作为代码页传递

编辑:我刚刚注意到内核标签。我引用的函数处于用户模式(kernel32.dll),因此可能对内核模式代码没有用处:(

是shell优于例程

RtlUnicodeToMultiByteN例程转换指定的Unicode 使用当前系统ANSI将字符串转换为新字符串 代码页(ACP)。翻译的字符串不一定来自 多字节字符集

因此,此例程中的任何一个都具有与CP\u ACP

还存在下一个例程:

-在例行程序中使用shell

RtlUnicodeToOemN例程将给定的Unicode字符串转换为 OEM字符串,使用当前系统OEM代码页

因此,该例程具有与CP\u OEMCP相同的转换

对于UTF-8存在转换(将Unicode字符串转换为UTF-8字符串)和(将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
    );

此处是初始化中的关键点,因此您可以使用任何USHORT代码页;此处

ANSI不是ASCII,请阅读并注意“翻译是根据当前系统区域设置信息完成的”。@RichardCriten我知道,但ANSI在前128个字符上始终与ASCII相同,因此我“[跳过]了129-255个区域设置/代码页”。是的,这是在内核模式驱动程序中运行的。我还关心如何理解现有代码。不过,感谢您的提示:)没问题!我同意该函数的错误条件文档非常模糊。在可能的情况下,0x007f以上的任何UTF-16字符都会映射到加载的ANSI代码页中的等效字符。不确定无法映射的UTF-16字符(2字节或4字节字符)是否会像某些Win32函数那样写入为“?”。写入为“?”是指实际将U+003F替换任何2字节或4字节字符?文档中说的唯一一件事是,如果返回代码不是STATUS\u SUCCESS,那么“没有分配存储,也没有进行转换”,因此我希望它不会更改字符,并且仍然返回STATUS\u SUCCESS。如果它不知道该做什么,它就不会进行转换,这可能是对的。谁知道…;-)
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
    );