383 lines
6.9 KiB
C++
383 lines
6.9 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (C) Microsoft Corporation, 1997 - 1999
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
unicodes
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This module implements the CUnicodeString class. This class allows a string
|
||
|
to automatically convert between PUNICODE_STRING, LPCSTR, and LPCWSTR.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Doug Barlow (dbarlow) 11/6/1997
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
Win32, C++
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
?Notes?
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#ifndef _WIN32_WINNT
|
||
|
#define _WIN32_WINNT 0x0400
|
||
|
#endif
|
||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||
|
#define WIN32_LEAN_AND_MEAN 1
|
||
|
#endif
|
||
|
#include <windows.h>
|
||
|
#include <wincrypt.h>
|
||
|
#include <crtdbg.h>
|
||
|
#include "scLogon.h"
|
||
|
#include "unicodes.h"
|
||
|
|
||
|
|
||
|
//
|
||
|
// Piddly routines.
|
||
|
//
|
||
|
|
||
|
CUnicodeString::CUnicodeString(
|
||
|
void)
|
||
|
{
|
||
|
m_szAnsi = NULL;
|
||
|
m_wszUnicode = NULL;
|
||
|
m_fFlags = fBothGood;
|
||
|
}
|
||
|
|
||
|
CUnicodeString::CUnicodeString(
|
||
|
LPCSTR sz)
|
||
|
{
|
||
|
m_szAnsi = NULL;
|
||
|
m_wszUnicode = NULL;
|
||
|
m_fFlags = fBothGood;
|
||
|
Set(sz);
|
||
|
}
|
||
|
|
||
|
CUnicodeString::CUnicodeString(
|
||
|
LPCWSTR wsz)
|
||
|
{
|
||
|
m_szAnsi = NULL;
|
||
|
m_wszUnicode = NULL;
|
||
|
m_fFlags = fBothGood;
|
||
|
Set(wsz);
|
||
|
}
|
||
|
|
||
|
CUnicodeString::CUnicodeString(
|
||
|
PUNICODE_STRING pus)
|
||
|
{
|
||
|
m_szAnsi = NULL;
|
||
|
m_wszUnicode = NULL;
|
||
|
m_fFlags = fBothGood;
|
||
|
Set(pus);
|
||
|
}
|
||
|
|
||
|
CUnicodeString::~CUnicodeString()
|
||
|
{
|
||
|
if (NULL != m_szAnsi)
|
||
|
{
|
||
|
memset(m_szAnsi, 0, lstrlenA(m_szAnsi));
|
||
|
LocalFree(m_szAnsi);
|
||
|
}
|
||
|
if (NULL != m_wszUnicode)
|
||
|
{
|
||
|
memset(m_wszUnicode, 0, lstrlenW(m_wszUnicode)*sizeof(WCHAR));
|
||
|
LocalFree(m_wszUnicode);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
PUNICODE_STRING
|
||
|
CUnicodeString::Set(
|
||
|
PUNICODE_STRING pus)
|
||
|
{
|
||
|
if (NULL != m_szAnsi)
|
||
|
{
|
||
|
LocalFree(m_szAnsi);
|
||
|
m_szAnsi = NULL;
|
||
|
}
|
||
|
if (NULL != m_wszUnicode)
|
||
|
{
|
||
|
LocalFree(m_wszUnicode);
|
||
|
m_wszUnicode = NULL;
|
||
|
}
|
||
|
m_fFlags = fNoneGood;
|
||
|
if (pus != NULL)
|
||
|
{
|
||
|
m_wszUnicode = (LPWSTR)LocalAlloc(LPTR, pus->Length + sizeof(WCHAR));
|
||
|
if (m_wszUnicode != NULL)
|
||
|
{
|
||
|
CopyMemory(
|
||
|
m_wszUnicode,
|
||
|
pus->Buffer,
|
||
|
pus->Length
|
||
|
);
|
||
|
m_wszUnicode[pus->Length/sizeof(WCHAR)] = L'\0';
|
||
|
m_fFlags = fUnicodeGood;
|
||
|
}
|
||
|
}
|
||
|
return pus;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Set:
|
||
|
|
||
|
These methods initialize the object to a given string.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
sz - Supplies an ANSI string with which to initialize the object.
|
||
|
|
||
|
wsz - Supplies a UNICODE string with which to initialize the object.
|
||
|
|
||
|
pus - Supplies a pointer to a UNICODE_STRING structure from which to
|
||
|
initialize the object.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
The same value as was provided.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Doug Barlow (dbarlow) 11/6/1997
|
||
|
|
||
|
--*/
|
||
|
|
||
|
LPCSTR
|
||
|
CUnicodeString::Set(
|
||
|
LPCSTR sz)
|
||
|
{
|
||
|
if (NULL != m_wszUnicode)
|
||
|
{
|
||
|
LocalFree(m_wszUnicode);
|
||
|
m_wszUnicode = NULL;
|
||
|
}
|
||
|
if (NULL != m_szAnsi)
|
||
|
LocalFree(m_szAnsi);
|
||
|
m_fFlags = fNoneGood;
|
||
|
|
||
|
m_szAnsi = (LPSTR)LocalAlloc(LPTR, (lstrlenA(sz) + 1) * sizeof(CHAR));
|
||
|
if (NULL != m_szAnsi)
|
||
|
{
|
||
|
lstrcpyA(m_szAnsi, sz);
|
||
|
m_fFlags = fAnsiGood;
|
||
|
}
|
||
|
return m_szAnsi;
|
||
|
}
|
||
|
|
||
|
LPCWSTR
|
||
|
CUnicodeString::Set(
|
||
|
LPCWSTR wsz)
|
||
|
{
|
||
|
if (NULL != m_szAnsi)
|
||
|
{
|
||
|
LocalFree(m_szAnsi);
|
||
|
m_szAnsi = NULL;
|
||
|
}
|
||
|
if (NULL != m_wszUnicode)
|
||
|
LocalFree(m_wszUnicode);
|
||
|
m_fFlags = fNoneGood;
|
||
|
m_wszUnicode = (LPWSTR)LocalAlloc(LPTR, (lstrlenW(wsz) + 1) * sizeof(WCHAR));
|
||
|
if (m_wszUnicode != NULL)
|
||
|
{
|
||
|
lstrcpyW(m_wszUnicode, wsz);
|
||
|
m_fFlags = fUnicodeGood;
|
||
|
}
|
||
|
return m_wszUnicode;
|
||
|
}
|
||
|
|
||
|
CUnicodeString::operator PUNICODE_STRING(
|
||
|
void)
|
||
|
{
|
||
|
m_us.Buffer = (LPWSTR)Unicode();
|
||
|
m_us.Length = m_us.MaximumLength = (USHORT)(lstrlenW(m_us.Buffer) * sizeof(WCHAR));
|
||
|
return &m_us;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Unicode:
|
||
|
|
||
|
This method ensures that the object has a valaid internal UNICODE
|
||
|
representation.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
The represented string, in UNICODE format.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Doug Barlow (dbarlow) 11/6/1997
|
||
|
|
||
|
--*/
|
||
|
|
||
|
LPCWSTR
|
||
|
CUnicodeString::Unicode(
|
||
|
void)
|
||
|
{
|
||
|
int length;
|
||
|
|
||
|
|
||
|
//
|
||
|
// See what data we've got, and if any conversion is necessary.
|
||
|
//
|
||
|
|
||
|
switch (m_fFlags)
|
||
|
{
|
||
|
case fAnsiGood:
|
||
|
// The ANSI value is good. Convert it to Unicode.
|
||
|
_ASSERTE(NULL != m_szAnsi);
|
||
|
length =
|
||
|
MultiByteToWideChar(
|
||
|
GetACP(),
|
||
|
MB_PRECOMPOSED,
|
||
|
m_szAnsi,
|
||
|
-1,
|
||
|
NULL,
|
||
|
0);
|
||
|
if (NULL != m_wszUnicode)
|
||
|
{
|
||
|
LocalFree(m_wszUnicode);
|
||
|
}
|
||
|
if (0 != length)
|
||
|
{
|
||
|
m_wszUnicode = (LPWSTR)LocalAlloc(LPTR, (length + 1) * sizeof(WCHAR));
|
||
|
if (m_wszUnicode == NULL)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
length =
|
||
|
MultiByteToWideChar(
|
||
|
GetACP(),
|
||
|
MB_PRECOMPOSED,
|
||
|
m_szAnsi,
|
||
|
-1,
|
||
|
m_wszUnicode,
|
||
|
length);
|
||
|
m_wszUnicode[length] = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_wszUnicode = NULL;
|
||
|
}
|
||
|
m_fFlags = fBothGood;
|
||
|
break;
|
||
|
|
||
|
case fUnicodeGood:
|
||
|
case fBothGood:
|
||
|
// The Unicode value is good. Just return that.
|
||
|
break;
|
||
|
|
||
|
case fNoneGood:
|
||
|
default:
|
||
|
// Internal error.
|
||
|
_ASSERT(FALSE);
|
||
|
break;
|
||
|
}
|
||
|
return m_wszUnicode;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Ansi:
|
||
|
|
||
|
This method ensures that the object has a valaid internal ANSI
|
||
|
representation.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
The represented string, in ANSI format.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Doug Barlow (dbarlow) 11/6/1997
|
||
|
|
||
|
--*/
|
||
|
|
||
|
LPCSTR
|
||
|
CUnicodeString::Ansi(
|
||
|
void)
|
||
|
{
|
||
|
int length;
|
||
|
|
||
|
|
||
|
//
|
||
|
// See what data we've got, and if any conversion is necessary.
|
||
|
//
|
||
|
|
||
|
switch (m_fFlags)
|
||
|
{
|
||
|
case fUnicodeGood:
|
||
|
// The Unicode buffer is good. Convert it to ANSI.
|
||
|
length =
|
||
|
WideCharToMultiByte(
|
||
|
GetACP(),
|
||
|
0,
|
||
|
m_wszUnicode,
|
||
|
-1,
|
||
|
NULL,
|
||
|
0,
|
||
|
NULL,
|
||
|
NULL);
|
||
|
if (NULL != m_szAnsi)
|
||
|
{
|
||
|
LocalFree(m_szAnsi);
|
||
|
}
|
||
|
|
||
|
if (0 != length)
|
||
|
{
|
||
|
m_szAnsi = (LPSTR)LocalAlloc(LPTR, (length + 1) * sizeof(CHAR));
|
||
|
if (m_szAnsi == NULL)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
length =
|
||
|
WideCharToMultiByte(
|
||
|
GetACP(),
|
||
|
0,
|
||
|
m_wszUnicode,
|
||
|
-1,
|
||
|
m_szAnsi,
|
||
|
length,
|
||
|
NULL,
|
||
|
NULL);
|
||
|
m_szAnsi[length] = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_szAnsi = NULL;
|
||
|
}
|
||
|
m_fFlags = fBothGood;
|
||
|
break;
|
||
|
|
||
|
case fAnsiGood:
|
||
|
case fBothGood:
|
||
|
// The ANSI buffer is good. We'll return that.
|
||
|
break;
|
||
|
|
||
|
case fNoneGood:
|
||
|
default:
|
||
|
// An internal error.
|
||
|
_ASSERT(FALSE);
|
||
|
break;
|
||
|
}
|
||
|
return m_szAnsi;
|
||
|
}
|
||
|
|