/*++ 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 #include #include #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; }