2016-07-13 22 views
1

Ich möchte den Puffer von einem UNICODE_STRING verwenden, aber es scheint, ich kann es nicht einfach direkt verwenden, indem ich Verweis kopieren, weil ich irgendwann sehen kann, dass Null Bytes in der Mitte einer Zeichenfolge sind, und Length ist größer als das, was ich im Debugger sehe. Also, wenn ich das tunUNICODE_STRING zu wchar_t * null beendet

UNICODE_STRING testStr; 
//after being used by some function it has data like this 'bad丣\0more_stuff\0' 

wchar_t * wStr = testStr.Buffer; 

werde ich mit wStr = "bad丣"; Ende Gibt es eine Möglichkeit, dies beendet die Null zu konvertieren, gültig wchar_t*?

+1

In welcher Codierung ist die Unicode-Zeichenkette? – 2501

+3

Sie haben also eine [double-null terminated string] (https://blogs.msdn.microsoft.com/oldnewthing/20091008-00/?p=16443). Nicht so ungewöhnlich. –

+1

Es funktioniert für jedes Zeichenfolgensystem, das '0' als Beendigungszeichen verwendet. –

Antwort

3

Ein wchar_t* ist nur ein Zeiger. Wenn Sie dem Debugger (oder einer anderen Funktion, an der Sie die wchar_t* übergeben) genau mitteilen, wie viele wchar_t Zeichen tatsächlich angezeigt werden, muss er irgendwo anhalten, damit er beim ersten Nullzeichen, auf das er stößt, stoppt.

UNICODE_STRING::Buffer ist nicht garantiert Null-terminiert, kann aber eingebettete Nullen enthalten. Sie müssen das Feld UNICODE_STRING::Length verwenden, um zu wissen, wie viele WCHAR Elemente in der Buffer sind, einschließlich eingebetteter Nullen, aber ohne einen abschließenden Nullabschluss, wenn einer vorhanden ist. Wenn Sie einen Nullabschluss benötigen, kopieren Sie die Buffer Daten in einen eigenen Puffer und fügen Sie einen Terminator hinzu.

Der einfachste Weg, das zu tun ist std::wstring zu verwenden, zB:

#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(); 

Die eingebetteten NULL-Werte immer noch vorhanden sein wird, aber c_str() wird das hintere Nullabschluss für Sie anhängen.Der Debugger zeigt die Daten weiterhin nur bis zum ersten Nullwert an, es sei denn, Sie geben dem Debugger die tatsächliche Anzahl der WCHAR Elemente in den Daten an.

Alternativ, wenn Sie wissen, dass die Buffer Daten durch Nullen getrennt mehrere Teil enthält, können Sie die Buffer Daten in ein Array von Strings statt optional aufgeteilt, zB:

#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... 

Oder:

#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... 
+0

[std :: string :: c_str()] (http://en.cppreference.com/w/cpp/string/basic_string/c_str) gibt einen Zeiger auf "const" zurück. – IInspectable

1

Eine ist eine Struktur, die sowohl Zeichendaten als auch ihre Länge speichert. Als solches erlaubt es eingebettete NUL-Zeichen, wie beispielsweise eine std::wstring.

Eine Zeichenfolge im C-Stil (z. B. wchar_t*) speichert dagegen keine explizite Zeichenfolge. Per Konvention wird es durch ein NUL-Zeichen beendet. Es ist Länge impliziert. Eine logische Folge davon ist, dass es keine eingebetteten NUL-Zeichen enthalten kann.

Das bedeutet, dass Sie nicht von UNICODE_STRING zu wchar_t* konvertieren können, ohne die Längeninformationen zu verlieren. Sie müssen die Länge entweder explizit neben dem Zeiger wchar_t* speichern oder Regeln für die Interpretation erstellen, die eine Neuberechnung der Länge ermöglichen (z. B. durch Interpretieren der Zeichenfolge als Zeichenfolge mit Doppel-Null-Ende). 1).


Zusätzliche Informationen:


1) Der Debugger eine wchar_t* als Null-terminierten String interpretiert. Wenn Sie die gesamte Sequenz anzeigen möchten, müssen Sie die Array-Größe explizit mit einer format specifier angeben.