768 lines
18 KiB
C++
768 lines
18 KiB
C++
/******************************************************************************
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
util.cpp
|
|
|
|
Abstract:
|
|
This file contains the implementation of common utility functions.
|
|
|
|
Revision History:
|
|
Seong Kook Khang (SKKhang) 07/07/99
|
|
created
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
#include "stdwin.h"
|
|
#include "resource.h"
|
|
#include "rstrpriv.h"
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Utility Functions
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#define CAL_TYPE_GREGORIAN_LOCALZED 1
|
|
#define CAL_TYPE_GREGORIAN_ENGLISH 2
|
|
#define CAL_TYPE_ERA_JAPAN 3
|
|
#define CAL_TYPE_ERA_TAIWAN 4
|
|
#define CAL_TYPE_ERA_KOREA 5
|
|
#define CAL_TYPE_ARABIC_HIJRI 6
|
|
#define CAL_TYPE_THAI 7
|
|
#define CAL_TYPE_HEBREW 8
|
|
#define CAL_TYPE_GREGORIAN_MIDDLE_EAST_FRENCH 9
|
|
#define CAL_TYPE_GREGORIAN_ARABIC 10
|
|
#define CAL_TYPE_GREGORIAN_TRANSLITERATED_ENGLISH 11
|
|
#define CAL_TYPE_GREGORIAN_TRANSLITERATED_FRENCH 12
|
|
|
|
#define CAL_RSTRUI_GREGORIAN 1
|
|
#define CAL_RSTRUI_OTHER 2
|
|
|
|
static int s_nCalType = CAL_RSTRUI_GREGORIAN ;
|
|
|
|
int SRUtil_SetCalendarTypeBasedOnLocale(LCID locale)
|
|
{
|
|
|
|
LPCWSTR cszErr;
|
|
int nRet;
|
|
WCHAR szCalType[8];
|
|
int nCalType;
|
|
|
|
nRet = ::GetLocaleInfo( locale,
|
|
LOCALE_ICALENDARTYPE,
|
|
szCalType,
|
|
sizeof(szCalType)/sizeof(WCHAR));
|
|
if ( nRet == 0 )
|
|
{
|
|
cszErr = ::GetSysErrStr();
|
|
// ErrorTrace(TRACE_ID, "GetLocaleInfo(%d) failed - %s", locale, cszErr);
|
|
goto Exit;
|
|
}
|
|
|
|
nCalType = ::_wtoi( szCalType );
|
|
|
|
if ( CAL_TYPE_GREGORIAN_LOCALZED == nCalType ||
|
|
CAL_TYPE_GREGORIAN_ENGLISH == nCalType ||
|
|
CAL_TYPE_GREGORIAN_MIDDLE_EAST_FRENCH == nCalType ||
|
|
CAL_TYPE_GREGORIAN_ARABIC == nCalType ||
|
|
CAL_TYPE_GREGORIAN_TRANSLITERATED_ENGLISH == nCalType ||
|
|
CAL_TYPE_GREGORIAN_TRANSLITERATED_FRENCH == nCalType )
|
|
{
|
|
s_nCalType = CAL_RSTRUI_GREGORIAN ;
|
|
}
|
|
else
|
|
{
|
|
s_nCalType = CAL_RSTRUI_OTHER ;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return nRet ;
|
|
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
LPSTR IStrDupA( LPCSTR szSrc )
|
|
{
|
|
TraceFunctEnter("IStrDupA");
|
|
int ccLen = 0 ;
|
|
LPSTR szNew = NULL;
|
|
|
|
if ( szSrc == NULL || szSrc[0] == '\0' )
|
|
goto Exit;
|
|
|
|
ccLen = ::lstrlenA( szSrc );
|
|
szNew = new char[ccLen+2];
|
|
|
|
if ( szNew != NULL )
|
|
{
|
|
::lstrcpyA( szNew, szSrc );
|
|
}
|
|
|
|
Exit:
|
|
TraceFunctLeave();
|
|
return( szNew );
|
|
}
|
|
|
|
/******************************************************************************/
|
|
|
|
LPWSTR IStrDupW( LPCWSTR wszSrc )
|
|
{
|
|
TraceFunctEnter("IStrDupW");
|
|
int ccLen = 0 ;
|
|
LPWSTR wszNew = NULL ;
|
|
|
|
if ( wszSrc == NULL || wszSrc[0] == L'\0' )
|
|
goto Exit;
|
|
|
|
ccLen = ::lstrlenW( wszSrc );
|
|
wszNew = new WCHAR[ccLen+2];
|
|
|
|
if ( wszNew != NULL )
|
|
{
|
|
::lstrcpyW( wszNew, wszSrc );
|
|
}
|
|
|
|
Exit:
|
|
TraceFunctLeave();
|
|
return( wszNew );
|
|
}
|
|
|
|
/****************************************************************************/
|
|
|
|
BOOL
|
|
SRFormatMessage( LPWSTR szMsg, UINT uFmtId, ... )
|
|
{
|
|
TraceFunctEnter("SRFormatMessage");
|
|
BOOL fRet = FALSE;
|
|
va_list marker;
|
|
WCHAR szFmt[MAX_STR_MSG];
|
|
|
|
va_start( marker, uFmtId );
|
|
::LoadString( g_hInst, uFmtId, szFmt, MAX_STR_MSG );
|
|
if ( 0 == ::FormatMessage( FORMAT_MESSAGE_FROM_STRING,
|
|
szFmt,
|
|
0,
|
|
0,
|
|
szMsg,
|
|
MAX_STR_MSG,
|
|
&marker ) )
|
|
{
|
|
LPCWSTR cszErr = ::GetSysErrStr();
|
|
ErrorTrace(0, "::FormatMessage failed - %ls", cszErr);
|
|
goto Exit;
|
|
}
|
|
va_end( marker );
|
|
|
|
fRet = TRUE;
|
|
Exit:
|
|
TraceFunctLeave();
|
|
return( fRet );
|
|
}
|
|
|
|
/****************************************************************************/
|
|
|
|
BOOL ShowSRErrDlg( UINT uMsgId, ... )
|
|
{
|
|
TraceFunctEnter("ShowSRErrDlg");
|
|
BOOL fRet = FALSE;
|
|
LPCWSTR cszErr;
|
|
va_list marker;
|
|
WCHAR szTitle[MAX_STR_TITLE];
|
|
WCHAR szFmt[MAX_STR_MSG];
|
|
WCHAR szMsg[MAX_STR_MSG];
|
|
|
|
if ( ::LoadString( g_hInst, IDS_RESTOREUI_TITLE, szTitle, MAX_STR_TITLE ) == 0 )
|
|
{
|
|
cszErr = ::GetSysErrStr();
|
|
ErrorTrace(0, "::LoadString(%u) failed - %ls", IDS_RESTOREUI_TITLE, cszErr);
|
|
goto Exit;
|
|
}
|
|
|
|
if ( ::LoadString( g_hInst, uMsgId, szFmt, MAX_STR_MSG ) == 0 )
|
|
{
|
|
cszErr = ::GetSysErrStr();
|
|
ErrorTrace(0, "::LoadString(%u) failed - %ls", uMsgId, cszErr);
|
|
goto Exit;
|
|
}
|
|
|
|
va_start( marker, uMsgId );
|
|
::wvsprintf( szMsg, szFmt, marker );
|
|
va_end( marker );
|
|
|
|
::MessageBox( NULL, szMsg, szTitle, MB_OK );
|
|
|
|
fRet = TRUE;
|
|
Exit:
|
|
TraceFunctLeave();
|
|
return( fRet );
|
|
}
|
|
|
|
/****************************************************************************/
|
|
|
|
BOOL SRGetRegDword( HKEY hKey, LPCWSTR cszSubKey, LPCWSTR cszValue, DWORD *pdwData )
|
|
{
|
|
TraceFunctEnter("SRGetRegDword");
|
|
BOOL fRet = FALSE;
|
|
DWORD dwType;
|
|
DWORD dwRes;
|
|
DWORD cbData;
|
|
|
|
dwType = REG_DWORD;
|
|
cbData = sizeof(DWORD);
|
|
dwRes = ::SHGetValue( hKey, cszSubKey, cszValue, &dwType, pdwData, &cbData );
|
|
if ( dwRes != ERROR_SUCCESS )
|
|
{
|
|
LPCWSTR cszErr = ::GetSysErrStr( dwRes );
|
|
ErrorTrace(0, "::SHGetValue failed - %ls", cszErr);
|
|
goto Exit;
|
|
}
|
|
|
|
fRet = TRUE;
|
|
Exit:
|
|
TraceFunctLeave();
|
|
return( fRet );
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*
|
|
static WCHAR s_wszPath[MAX_PATH];
|
|
|
|
LPWSTR PathElem2Str( PathElement *pElem )
|
|
{
|
|
TraceFunctEnter("PathElem2Str");
|
|
int cch = pElem->pe_length / sizeof(USHORT) - 1;
|
|
|
|
::StrCpyNW( s_wszPath, pElem->pe_unichars, cch+1 );
|
|
// for ( int i = 0; i < ccLen; i++ )
|
|
// wszElem[i] = pElem->pe_unichars[i];
|
|
s_wszPath[cch] = '\0';
|
|
|
|
TraceFunctLeave();
|
|
return( s_wszPath );
|
|
}
|
|
|
|
LPWSTR ParsedPath2Str( ParsedPath *pPath, LPCWSTR wszDrive )
|
|
{
|
|
TraceFunctEnter("ParsedPath2Str");
|
|
LPWSTR wszAppend;
|
|
PathElement *pElem;
|
|
int cch;
|
|
|
|
if ( pPath != NULL )
|
|
{
|
|
::lstrcpyW( s_wszPath, wszDrive );
|
|
wszAppend = s_wszPath + ::lstrlenW( s_wszPath );
|
|
|
|
for ( pElem = pPath->pp_elements; pElem->pe_length > 0; pElem = IFSNextElement( pElem ) )
|
|
{
|
|
DebugTrace(0, "pElem->pe_length=%d", pElem->pe_length);
|
|
*wszAppend++ = L'\\';
|
|
cch = pElem->pe_length / sizeof(USHORT) - 1;
|
|
::StrCpyNW( wszAppend, pElem->pe_unichars, cch+1 );
|
|
wszAppend += cch;
|
|
}
|
|
*wszAppend = L'\0';
|
|
}
|
|
else
|
|
{
|
|
*s_wszPath = L'\0';
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
return( s_wszPath );
|
|
}
|
|
*/
|
|
|
|
/******************************************************************************/
|
|
|
|
//
|
|
// Check if we have enough free space in Windows directory and this is
|
|
// greater than the minimum requirments for carrying out a restore, this
|
|
// also reads and caches the registry data. If registry data cannot be
|
|
// read defaults in the code will be used
|
|
//
|
|
BOOL IsFreeSpaceOnWindowsDrive( void )
|
|
{
|
|
|
|
TraceFunctEnter("IsFreeSpaceOnWindowsDrive");
|
|
|
|
static BOOL fFirstTime = TRUE ;
|
|
static DWORD dwMinValidSpace = RSTRMAP_MIN_WIN_DISK_SPACE_MB * (1024 * 1024) ;
|
|
static WCHAR szWinPath[MAX_PATH+1];
|
|
|
|
ULARGE_INTEGER i64FreeBytesToCaller;
|
|
ULARGE_INTEGER i64FreeBytes ;
|
|
ULARGE_INTEGER i64TotalBytes ;
|
|
BOOL fResult = FALSE ;
|
|
BOOL fRetVal = TRUE ;
|
|
DWORD dwError;
|
|
LPCWSTR cszErr;
|
|
|
|
long lRetVal = 0;
|
|
HKEY hKey = NULL;
|
|
DWORD dwVal = 0;
|
|
DWORD dwType = 0;
|
|
DWORD cbData = sizeof(DWORD);
|
|
|
|
//
|
|
// Read registry and get the size of FreezeSize and set the min
|
|
// size for disk on data store
|
|
//
|
|
if ( fFirstTime )
|
|
{
|
|
|
|
#ifdef LEGACY_CODE
|
|
if ( !::GetWindowsDirectory( szWinPath, MAX_PATH ) )
|
|
{
|
|
cszErr = GetSysErrStr();
|
|
ErrorTrace(TRACE_ID, "::GetWindowsDirectory failed - %s", cszErr);
|
|
goto Exit;
|
|
}
|
|
|
|
DebugTrace(TRACE_ID, "Opening: %s", s_cszReservedDiskSpaceKey);
|
|
|
|
//
|
|
// Open HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\StateMgr\ReservedDiskSpace
|
|
// for reading
|
|
//
|
|
lRetVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
s_cszReservedDiskSpaceKey,
|
|
0,
|
|
KEY_READ,
|
|
&hKey);
|
|
|
|
if( ERROR_SUCCESS == lRetVal)
|
|
{
|
|
|
|
DebugTrace(TRACE_ID, "Querying: %s", s_cszUIFreezeSize);
|
|
|
|
//
|
|
// Read "FreezeSize"
|
|
//
|
|
lRetVal = RegQueryValueEx(hKey,
|
|
s_cszUIFreezeSize,
|
|
0,
|
|
&dwType,
|
|
(LPBYTE)&dwVal,
|
|
&cbData);
|
|
|
|
if( ERROR_SUCCESS == lRetVal)
|
|
{
|
|
if ( dwVal < RSTRMAP_LOW_WIN_DISK_SPACE_MB )
|
|
{
|
|
dwVal = RSTRMAP_LOW_WIN_DISK_SPACE_MB;
|
|
};
|
|
dwMinValidSpace = dwVal * (1024 * 1024) ;
|
|
}
|
|
else
|
|
{
|
|
ErrorTrace(TRACE_ID, "RegQueryValueEx failed; hr=0x%x", GetLastError());
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
ErrorTrace(TRACE_ID, "RegOpenKeyEx failed; hr=0x%x", GetLastError());
|
|
}
|
|
#endif //def LEGACY_CODE
|
|
|
|
fFirstTime = FALSE ;
|
|
}
|
|
|
|
|
|
fRetVal = TRUE ;
|
|
|
|
fResult = GetDiskFreeSpaceEx(szWinPath,
|
|
(PULARGE_INTEGER) &i64FreeBytesToCaller,
|
|
(PULARGE_INTEGER) &i64TotalBytes,
|
|
(PULARGE_INTEGER) &i64FreeBytes);
|
|
|
|
if ( fResult )
|
|
{
|
|
//
|
|
// Now check if disk free space is greater than min space (high 4GB)
|
|
//
|
|
if (i64FreeBytes.HighPart > 0 )
|
|
{
|
|
goto Exit;
|
|
}
|
|
else if (i64FreeBytesToCaller.LowPart > dwMinValidSpace )
|
|
{
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
fRetVal = FALSE ;
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// If the function fails its Ok to try to go on as the Restore Undo
|
|
// should handle it if things get very full
|
|
//
|
|
dwError = ::GetLastError();
|
|
ErrorTrace(TRACE_ID, "GetDiskFreeSpaceEx failed. ec=%d", dwError);
|
|
goto Exit;
|
|
|
|
};
|
|
|
|
Exit:
|
|
|
|
TraceFunctLeave();
|
|
|
|
return fRetVal ;
|
|
|
|
}
|
|
|
|
//
|
|
// Get the default language for the current user
|
|
//
|
|
LANGID GetDefaultUILang(void)
|
|
{
|
|
OSVERSIONINFO Osv ;
|
|
BOOL IsWindowsNT ;
|
|
|
|
LANGID wUILang = MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US);
|
|
|
|
Osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ;
|
|
|
|
if(!GetVersionEx(&Osv))
|
|
{
|
|
goto Exit ;
|
|
}
|
|
|
|
IsWindowsNT = (BOOL) (Osv.dwPlatformId == VER_PLATFORM_WIN32_NT) ;
|
|
|
|
//
|
|
// Get the UI language by one of three methods, depending on the system
|
|
//
|
|
if(!IsWindowsNT)
|
|
{
|
|
//
|
|
// Case 1: Running on Windows 9x. Get the system UI language from registry:
|
|
//
|
|
CHAR szData[32] ;
|
|
DWORD dwErr, dwSize = sizeof(szData) ;
|
|
HKEY hKey ;
|
|
|
|
dwErr = RegOpenKeyEx(
|
|
HKEY_USERS,
|
|
TEXT(".Default\\Control Panel\\desktop\\ResourceLocale"),
|
|
0,
|
|
KEY_READ,
|
|
&hKey
|
|
) ;
|
|
|
|
if(ERROR_SUCCESS != dwErr)
|
|
{
|
|
goto Exit ;
|
|
}
|
|
|
|
dwErr = RegQueryValueEx(
|
|
hKey,
|
|
TEXT(""),
|
|
NULL, //reserved
|
|
NULL, //type
|
|
(LPBYTE) szData,
|
|
&dwSize
|
|
) ;
|
|
|
|
if(ERROR_SUCCESS != dwErr)
|
|
{
|
|
goto Exit ;
|
|
}
|
|
|
|
dwErr = RegCloseKey(hKey) ;
|
|
|
|
// Convert string to number
|
|
wUILang = (LANGID) strtol(szData, NULL, 16) ;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return wUILang ;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CSRStr
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
CSRStr::CSRStr()
|
|
{
|
|
TraceFunctEnter("CSRStr::CSRStr()");
|
|
|
|
m_cchW = 0;
|
|
m_strW = NULL;
|
|
m_cchA = 0;
|
|
m_strA = NULL;
|
|
|
|
TraceFunctLeave();
|
|
}
|
|
|
|
CSRStr::CSRStr( LPCWSTR wszSrc )
|
|
{
|
|
TraceFunctEnter("CSRStr::CSRStr(LPCWSTR)");
|
|
|
|
m_strW = NULL;
|
|
m_strA = NULL;
|
|
SetStr( wszSrc );
|
|
|
|
TraceFunctLeave();
|
|
}
|
|
|
|
CSRStr::CSRStr( LPCSTR szSrc )
|
|
{
|
|
TraceFunctEnter("CSRStr::CSRStr(LPCSTR)");
|
|
|
|
m_strW = NULL;
|
|
m_strA = NULL;
|
|
SetStr( szSrc );
|
|
|
|
TraceFunctLeave();
|
|
}
|
|
|
|
CSRStr::~CSRStr()
|
|
{
|
|
TraceFunctEnter("CSRStr::~CSRStr");
|
|
|
|
Empty();
|
|
|
|
TraceFunctLeave();
|
|
}
|
|
|
|
int CSRStr::LengthW()
|
|
{
|
|
TraceFunctEnter("CSRStr::CountW");
|
|
|
|
if ( m_cchW == 0 && m_strA != NULL )
|
|
ConvertA2W();
|
|
|
|
TraceFunctLeave();
|
|
return( m_cchW );
|
|
}
|
|
|
|
int CSRStr::LengthA()
|
|
{
|
|
TraceFunctEnter("CSRStr::CountA");
|
|
|
|
if ( m_cchA == 0 && m_strW != NULL )
|
|
ConvertW2A();
|
|
|
|
TraceFunctLeave();
|
|
return( m_cchA );
|
|
}
|
|
|
|
CSRStr::operator LPCWSTR()
|
|
{
|
|
TraceFunctEnter("CSRStr::operator LPCWSTR");
|
|
|
|
if ( m_strW == NULL && m_strA != NULL )
|
|
ConvertA2W();
|
|
|
|
TraceFunctLeave();
|
|
return( m_strW );
|
|
}
|
|
|
|
CSRStr::operator LPCSTR()
|
|
{
|
|
TraceFunctEnter("CSRStr::operator LPCSTR");
|
|
|
|
if ( m_strA == NULL && m_strW != NULL )
|
|
ConvertW2A();
|
|
|
|
TraceFunctLeave();
|
|
return( m_strA );
|
|
}
|
|
|
|
void CSRStr::Empty()
|
|
{
|
|
TraceFunctEnter("CSRStr::Empty");
|
|
|
|
if ( m_strW != NULL )
|
|
{
|
|
delete [] m_strW;
|
|
m_strW = NULL;
|
|
m_cchW = 0;
|
|
}
|
|
if ( m_strA != NULL )
|
|
{
|
|
delete [] m_strA;
|
|
m_strA = NULL;
|
|
m_cchA = 0;
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
}
|
|
|
|
BOOL CSRStr::SetStr( LPCWSTR wszSrc, int cch )
|
|
{
|
|
TraceFunctEnter("CSRStr::SetStr(LPCWSTR,int)");
|
|
BOOL fRet = FALSE;
|
|
|
|
Empty();
|
|
|
|
if ( wszSrc == NULL )
|
|
goto Exit;
|
|
|
|
if ( cch == -1 )
|
|
cch = ::lstrlenW( wszSrc );
|
|
|
|
if ( cch > 0 )
|
|
{
|
|
m_strW = new WCHAR[cch+2];
|
|
if ( m_strW == NULL )
|
|
{
|
|
ErrorTrace(TRACE_ID, "Insufficient memory...");
|
|
goto Exit;
|
|
}
|
|
::StrCpyNW( m_strW, wszSrc, cch+1 );
|
|
m_strW[cch] = L'\0';
|
|
m_cchW = cch;
|
|
}
|
|
|
|
fRet = TRUE;
|
|
Exit:
|
|
TraceFunctLeave();
|
|
return( fRet );
|
|
}
|
|
|
|
BOOL CSRStr::SetStr( LPCSTR szSrc, int cch )
|
|
{
|
|
TraceFunctEnter("CSRStr::SetStr(LPCSTR,int)");
|
|
BOOL fRet = FALSE;
|
|
|
|
Empty();
|
|
|
|
if ( szSrc == NULL )
|
|
goto Exit;
|
|
|
|
if ( cch == -1 )
|
|
cch = ::lstrlenA( szSrc );
|
|
|
|
if ( cch > 0 )
|
|
{
|
|
m_strA = new char[cch+2];
|
|
if ( m_strA == NULL )
|
|
{
|
|
ErrorTrace(TRACE_ID, "Insufficient memory...");
|
|
goto Exit;
|
|
}
|
|
::lstrcpynA( m_strA, szSrc, cch+1 );
|
|
m_strA[cch] = L'\0';
|
|
m_cchA = cch;
|
|
}
|
|
|
|
fRet = TRUE;
|
|
Exit:
|
|
TraceFunctLeave();
|
|
return( fRet );
|
|
}
|
|
|
|
const CSRStr& CSRStr::operator =( LPCWSTR wszSrc )
|
|
{
|
|
TraceFunctEnter("CSRStr::operator =(LPCWSTR)");
|
|
|
|
SetStr( wszSrc );
|
|
|
|
TraceFunctLeave();
|
|
return( *this );
|
|
}
|
|
|
|
const CSRStr& CSRStr::operator =( LPCSTR szSrc )
|
|
{
|
|
TraceFunctEnter("CSRStr::operator =(LPCSTR)");
|
|
|
|
SetStr( szSrc );
|
|
|
|
TraceFunctLeave();
|
|
return( *this );
|
|
}
|
|
|
|
BOOL CSRStr::ConvertA2W()
|
|
{
|
|
TraceFunctEnter("CSRStr::ConvertA2W");
|
|
BOOL fRet = FALSE;
|
|
LPCWSTR cszErr;
|
|
int cch;
|
|
|
|
cch = ::MultiByteToWideChar( CP_ACP, 0, m_strA, m_cchA, NULL, 0 );
|
|
if ( cch == 0 )
|
|
{
|
|
cszErr = ::GetSysErrStr();
|
|
ErrorTrace(TRACE_ID, "::MultiByteToWideChar failed - %s", cszErr);
|
|
goto Exit;
|
|
}
|
|
m_strW = new WCHAR[cch+2];
|
|
if ( m_strW == NULL )
|
|
{
|
|
ErrorTrace(TRACE_ID, "Insufficient memory...");
|
|
goto Exit;
|
|
}
|
|
m_cchW = ::MultiByteToWideChar( CP_ACP, 0, m_strA, m_cchA, m_strW, cch );
|
|
if ( m_cchW != cch )
|
|
{
|
|
ErrorTrace(TRACE_ID, "::MultiByteToWideChar returns inconsistent length - %d / %d", cch, m_cchW);
|
|
delete [] m_strW;
|
|
m_strW = NULL;
|
|
m_cchW = 0;
|
|
goto Exit;
|
|
}
|
|
m_strW[m_cchW] = L'\0';
|
|
|
|
fRet = TRUE;
|
|
Exit:
|
|
TraceFunctLeave();
|
|
return( fRet );
|
|
}
|
|
|
|
BOOL CSRStr::ConvertW2A()
|
|
{
|
|
TraceFunctEnter("CSRStr::ConvertW2A");
|
|
BOOL fRet = FALSE;
|
|
LPCWSTR cszErr;
|
|
int cch;
|
|
|
|
cch = ::WideCharToMultiByte( CP_ACP, 0, m_strW, m_cchW, NULL, 0, NULL, NULL );
|
|
if ( cch == 0 )
|
|
{
|
|
cszErr = GetSysErrStr();
|
|
ErrorTrace(TRACE_ID, "::WideCharToMultiByte failed - %s", cszErr);
|
|
goto Exit;
|
|
}
|
|
m_strA = new char[cch+2];
|
|
if ( m_strA == NULL )
|
|
{
|
|
ErrorTrace(TRACE_ID, "Insufficient memory...");
|
|
goto Exit;
|
|
}
|
|
m_cchA = ::WideCharToMultiByte( CP_ACP, 0, m_strW, m_cchW, m_strA, cch, NULL, NULL );
|
|
if ( m_cchA != cch )
|
|
{
|
|
ErrorTrace(TRACE_ID, "::WideCharToMultiByte returns inconsistent length - %d / %d", cch, m_cchA);
|
|
delete [] m_strA;
|
|
m_strA = NULL;
|
|
m_cchA = 0;
|
|
goto Exit;
|
|
}
|
|
m_strA[m_cchA] = '\0';
|
|
|
|
fRet = TRUE;
|
|
Exit:
|
|
TraceFunctLeave();
|
|
return( fRet );
|
|
}
|
|
|
|
|
|
// end of file
|