2008-11-03 2 views
0

UNICODE_STRING 구조체를 간단한 NULL TERMINATED STRING으로 변환해야합니다.Null로 UNICODE_STRING이 종료되었습니다.

typedef 
struct _UNICODE_STRING 
{ 
    USHORT Length; 
    USHORT MaximumLength; 
    PWSTR Buffer; 
} 
UNICODE_STRING, *PUNICODE_STRING; 

MSDN에서 깨끗한 해결책을 찾을 수 없습니다. 누구 없습니까? .net을 사용하지 않으므로 기본 API 해결 방법이 필요합니다.

고맙습니다.

+2

"NULL TERMINATED STRING"이라고 말하면 null로 끝나는 wchar_t 문자열 또는 null로 끝나는 ASCII/멀티 바이트 문자열을 의미합니까? –

답변

3

WideCharToMultiByte를 사용해야합니다. 출력 버퍼 크기에 대한 추정치로서 길이 필드를 사용할 수 있지만 실제 다중 바이트 문자열의 경우를 고려하십시오.이 경우 ERROR_INSUFFICIENT_BUFFER로 실패하고 큰 버퍼로 다시 시작해야합니다. 또는 항상 출력 버퍼 크기를 0으로 호출하여 필요한 버퍼 크기를 알려줍니다.

0
WCHAR* UnicodeStringToNulTerminated(UNICODE_STRING* str) 
{ 
    WCHAR* result; 
    if(str == NULL) 
    return NULL; 
    result = (WCHAR*)malloc(result->Length + 2); 
    if(result == NULL) 
    // raise? 
    return NULL; 
    memcpy(result, str->Buffer, str->Length); 
    result[str->Length] = L'\0'; 
    return result; 
} 
+0

'result-> Length'는 'str-> Length'여야합니다. – BCran

1

유니 코드를 컴파일 및 ANSI로 변환이 작동하는 표시 나
(http://support.microsoft.com/kb/138813에서 수정이) :

HRESULT UnicodeToAnsi(LPCOLESTR pszW, LPSTR* ppszA){ 
    ULONG cbAnsi, cCharacters; 
    DWORD dwError; 
    // If input is null then just return the same.  
    if (pszW == NULL)  
    { 
     *ppszA = NULL; 
     return NOERROR; 
    } 
    cCharacters = wcslen(pszW)+1; 
    cbAnsi = cCharacters*2; 

    *ppszA = (LPSTR) CoTaskMemAlloc(cbAnsi); 
    if (NULL == *ppszA) 
     return E_OUTOFMEMORY; 

    if (0 == WideCharToMultiByte(CP_ACP, 0, pszW, cCharacters, *ppszA, cbAnsi, NULL, NULL)) 
    { 
     dwError = GetLastError(); 
     CoTaskMemFree(*ppszA); 
     *ppszA = NULL; 
     return HRESULT_FROM_WIN32(dwError); 
    } 
    return NOERROR; 
} 


사용법 :

LPSTR pszstrA; 
UnicodeToAnsi(my_unicode_string.Buffer, &pszstrA); 
cout << "My ansi string: (" << pszstrA << ")\r\n"; 
+0

버퍼가 0으로 종료되지 않으면 wcslen이 작동하지 않습니다. – glagolig

0

ANSI 또는 UN이 필요한지 여부를 말하지 않았으므로 ANSI로 변환 WideCharToMultiByte는 매개 변수로 전달되어야한다 UNICODE_STRING에서 유니 코드 문자의 수를 필요로하지 않습니다

#include <string> 

UNICODE_STRING us; 
// fill us as needed... 

std::wstring ws(us.Buffer, us.Length); 
// use ws.c_str() where needed... 
0

대체 코드 : ICODE 널 (NULL) 종료 문자열, 나는 유니 코드를 가정하겠습니다. UNICODE_STRING.Length는 유니 코드 문자가 아닌 바이트 수이며 버퍼가 0으로 종료되지 않으면 wcslen이 작동하지 않습니다.

UNICODE_STRING tmp; 
// ... 
STRING dest; // or ANSI_STRING in kernel mode 

LONG (WINAPI *RtlUnicodeStringToAnsiString)(PVOID, PVOID, BOOL); 
*(FARPROC *)&RtlUnicodeStringToAnsiString = 
    GetProcAddress(LoadLibraryA("NTDLL.DLL"), "RtlUnicodeStringToAnsiString"); 
if(!RtlUnicodeStringToAnsiString) 
{ 
    return; 
} 

ULONG unicodeBufferSize = tmp.Length; 
dest.Buffer = (PCHAR)malloc(unicodeBufferSize+1); // that must be enough... 
dest.Length = 0; 
dest.MaximumLength = unicodeBufferSize+1; 

RtlUnicodeStringToAnsiString(&dest, &tmp, FALSE); 
dest.Buffer[dest.Length] = 0; // now we get it in dest.Buffer