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