UNICODE_STRING到wchar_t * null终止

时间:2016-07-13 05:03:53

标签: c++ c winapi unicode-string wchar

我想使用来自A10000的缓冲区,但似乎我不能直接使用它,通过复制引用,因为有时我可以看到字符串中间有空字节,{ {1}}比我在调试器中看到的要大。所以,如果我这样做

UNICODE_STRING

我最终会以Length结束 有没有办法将其转换为空终止,有效UNICODE_STRING testStr; //after being used by some function it has data like this 'bad丣\0more_stuff\0' wchar_t * wStr = testStr.Buffer;

2 个答案:

答案 0 :(得分:3)

wchar_t*只是一个指针。除非你告诉调试器(或你传递wchar_t*的任何函数)确切地指出了多少wchar_t个字符,否则它必须停在某处,所以它会在它遇到的第一个空字符处停止

UNICODE_STRING::Buffer不保证以空值终止,但它可以包含嵌入的空值。您必须使用UNICODE_STRING::Length字段来了解WCHAR中有多少Buffer个元素,包括嵌入的空值,但如果存在,则不计算尾随的空终止符。如果需要空终止符,请将Buffer数据复制到您自己的缓冲区并附加终止符。

最简单的方法是使用std::wstring,例如:

#include <string>

UNICODE_STRING testStr;
// fill testStr as needed...

std::wstring wStrBuf(testStr.Buffer, testStr.Length / sizeof(WCHAR));
const wchar_t *wStr = wStrBuf.c_str();

嵌入的空值仍然存在,但c_str()将为您附加尾随的空终止符。 调试器仍将仅显示第一个空值,除非您告诉调试器数据中实际有WCHAR个元素的数量。

或者,如果您知道Buffer数据包含由空值分隔的多个子字符串,则可以选择将Buffer数据拆分为字符串数组,例如:

#include <string>
#include <vector>

UNICODE_STRING testStr;
// fill testStr as needed...

std::vector<std::wstring> wStrArr;

std::wstring wStr(testStr.Buffer, testStr.Length / sizeof(WCHAR));
std::wstring::size_type startidx = 0;
do
{
    std::wstring::size_type idx = wStr.find(L'\0', startidx);
    if (idx == std::wstring::npos)
    {
        if (startidx < wStr.size())
        {
            if (startidx > 0)
                wStrArr.push_back(wStr.substr(startidx));
            else
                wStrArr.push_back(wStr);
        }
        break;
    }
    wStrArr.push_back(wStr.substr(startidx, idx-startidx));
    startidx = idx + 1;
}
while (true);

// use wStrArr as needed...

或者:

#include <vector>
#include <algorithm>

UNICODE_STRING testStr;
// fill testStr as needed...

std::vector<std::wstring> wStrArr;

WCHAR *pStart = testStr.Buffer;
WCHAR *pEnd = pStart + (testStr.Length / sizeof(WCHAR));

do
{
    WCHAR *pFound = std::find(pStart, pEnd, L'\0');
    if (pFound == pEnd)
    {
        if (pStart < pEnd)
            wStrArr.push_back(std::wstring(pStart, pEnd-pStart));
        break;
    }
    wStrArr.push_back(std::wstring(pStart, pFound-pStart));
    pStart = pFound + 1;
}
while (true);

// use wStrArr as needed...

答案 1 :(得分:1)

UNICODE_STRING是一种结构,用于存储字符数据及其长度。因此,它允许嵌入的NUL字符,例如std::wstring

另一方面,C风格的字符串(例如wchar_t*)不存储显式字符串长度。按照惯例,它以NUL字符终止。它的长度是隐含的。其必然结果是,它不能包含嵌入的NUL字符。

这意味着您无法在不丢失长度信息的情况下从UNICODE_STRING转换为wchar_t*。您必须显式地存储长度,与wchar_t*指针一起存储,或者建立解释规则,以允许重新计算长度(例如,通过将字符序列解释为以双空终止的字符串) 1 )

<小时/> 其他信息:

<小时/> 1) 调试器将wchar_t*解释为以零结尾的字符串。如果要查看整个序列,则需要使用format specifier显式提供数组大小。