|
|
/******************************************************************************
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
|