|
|
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2001, Microsoft Corporation All rights reserved.
//
// Module Name:
//
// util.c
//
// Abstract:
//
// This file contains the accessory function of the euroconv.exe utility.
//
// Revision History:
//
// 2001-07-30 lguindon Created.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
// Include Files.
//
///////////////////////////////////////////////////////////////////////////////
#include "euroconv.h"
#include "util.h"
///////////////////////////////////////////////////////////////////////////////
//
// Global Variables.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
// AddExceptionOverride
//
// Add locale to the exception locale list. The memory referenced by elem
// is initialized to zero so, don't worry to return something correct when
// failling.
//
///////////////////////////////////////////////////////////////////////////////
void AddExceptionOverride(PEURO_EXCEPTION elem, LPSTR strBuf) { LPSTR szLocale = NULL; LCID locale; LPSTR szSeparator = NULL; LPSTR szThouSeparator = NULL; LPSTR szDigits = NULL; BOOL bInsideQuote = FALSE;
//
// Change the separator used between each block in order to avoid
// mistake with the data itself inside the double quote.
//
szLocale = strBuf; while (*szLocale) { if (*szLocale == '"') { bInsideQuote = bInsideQuote ? FALSE : TRUE; } else if (*szLocale == ',') { if (!bInsideQuote) { *szLocale = '#'; } } szLocale++; }
//
// Scan the string and validate substrings
//
szLocale = strBuf; if (szSeparator = strchr(strBuf,'#')) { *szSeparator = '\0'; szSeparator++; if (szDigits = strchr(szSeparator,'#')) { *szDigits = '\0'; szDigits++; if (szThouSeparator = strchr(szDigits,'#')) { *szThouSeparator = '\0'; szThouSeparator++; } else { return; } } else { return; } } else { return; }
//
// Remove quotes.
//
szLocale = RemoveQuotes(szLocale); szSeparator = RemoveQuotes(szSeparator); szDigits = RemoveQuotes(szDigits); szThouSeparator = RemoveQuotes(szThouSeparator);
//
// Check if the locale contains 0x in it.
//
if ((szLocale[0] == '0') && ((szLocale[1] == 'X') || (szLocale[1] == 'x'))) { locale = (LCID)TransNum(szLocale+2); // skip 0x
} else { locale = (LCID)TransNum(szLocale); } //
// Validate
//
if ( IsValidLocale(locale, LCID_INSTALLED) && (strlen(szSeparator) <= MAX_SMONDECSEP) && (strlen(szDigits) <= MAX_ICURRDIGITS) && (strlen(szThouSeparator) <= MAX_SMONTHOUSEP)) { elem->dwLocale = locale; //strcpy(elem->chThousandSep, szThouSeparator);
//strcpy(elem->chDecimalSep, szSeparator);
//strcpy(elem->chDigits, szDigits);
StringCbCopy(elem->chDigits, MAX_ICURRDIGITS + 1, szDigits); StringCbCopy(elem->chDecimalSep, MAX_SMONDECSEP + 1, szSeparator); StringCbCopy(elem->chThousandSep, MAX_SMONTHOUSEP + 1, szThouSeparator); } }
///////////////////////////////////////////////////////////////////////////////
//
// CleanUp
//
// Free memory represented by the handle.
//
///////////////////////////////////////////////////////////////////////////////
void CleanUp(HGLOBAL handle) { if (handle != NULL) { GlobalUnlock(handle); GlobalFree(handle); } }
///////////////////////////////////////////////////////////////////////////////
//
// IsAdmin
//
// Verify is the user has administrative rights.
//
///////////////////////////////////////////////////////////////////////////////
BOOL IsAdmin() { BOOL bRet = FALSE; HKEY hKey;
//
// No security on the registry for Windows 9x platfom.
//
if (IsWindows9x()) { return (TRUE); } //
// See if the user has Administrative privileges by checking for
// write permission to the registry key.
//
if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Nls", 0UL, KEY_WRITE, &hKey ) == ERROR_SUCCESS) { //
// See if the user can write into the registry. Due to a registry
// modification, we can open a registry key with write access and
// be unable to write to the key... thanks to terminal server.
//
if (RegSetValueEx( hKey, "Test", 0UL, REG_SZ, (LPBYTE)"Test", (DWORD)(lstrlen("Test") + 1) * sizeof(TCHAR) ) == ERROR_SUCCESS) { //
// Delete the value created.
//
RegDeleteValue(hKey, "Test");
//
// We can write to the HKEY_LOCAL_MACHINE key, so the user
// has Admin privileges.
//
bRet = TRUE; }
//
// Clean up.
//
RegCloseKey(hKey); }
//
// Return the value
//
return (bRet); }
///////////////////////////////////////////////////////////////////////////////
//
// IsEuroPatchInstalled
//
// Verify if the Euro patch is installed. Check if the symbol for the Euro
// currency is part of different locale.
//
///////////////////////////////////////////////////////////////////////////////
BOOL IsEuroPatchInstalled() { WCHAR baseStr[] = L"\x20AC"; CHAR ansiStr[8] = {0}; WCHAR retStr[8] = {0};
#ifdef DEBUG
//
// Patch detection override
//
if (!gbPatchCheck) { return (TRUE); } #endif // DEBUG
//
// Convert the string to ANSI.
//
WideCharToMultiByte( 1252, WC_COMPOSITECHECK | WC_SEPCHARS, baseStr, -1, ansiStr, 8, NULL, NULL);
//
// Convert back the base string to Unicode.
//
MultiByteToWideChar( 1252, MB_PRECOMPOSED, ansiStr, 8, retStr, 8 ); //
// Compare if the result is the same.
//
if (_wcsicmp(retStr, baseStr) == 0) { return (TRUE); }
//
// Return default value.
//
return (FALSE); }
///////////////////////////////////////////////////////////////////////////////
//
// IsWindows9x
//
// Verify the operating system is Windows 9x.
//
///////////////////////////////////////////////////////////////////////////////
BOOL IsWindows9x() { //
// Check if the value have been already initialized.
//
if (gdwVersion == (-1)) { DWORD dwVersion = GetVersion();
if(dwVersion >= 0x80000000) { //
// GetVersion claims its Win9x, lets see if it is truthful.
// (gets around App Compat stuff that would claim Win9x-ness).
//
if((INVALID_FILE_ATTRIBUTES == GetFileAttributesW(L"???.???")) && (ERROR_INVALID_NAME == GetLastError())) { //
// If GetFileAttributesW is functional, then it is *not* Win9x.
// It could be any version of NT, we'll call it XP for grins since
// it does not matter what kind of NT it is for our purposes.
//
dwVersion = 0x0A280105; } }
//
// Check for Windows 9x flavor
//
if (dwVersion >= 0x80000000) { gdwVersion = 1; } else { gdwVersion = 0; } }
return (BOOL)gdwVersion; }
////////////////////////////////////////////////////////////////////////////
//
// ShowMsg
//
// Display an error message to the display.
//
////////////////////////////////////////////////////////////////////////////
int ShowMsg(HWND hDlg, UINT iMsg, UINT iTitle, UINT iType) { TCHAR szTitle[MAX_PATH] = {0}; TCHAR szErrMsg[MAX_PATH*8] = {0}; LPTSTR pTitle = NULL;
if (iTitle) { if (LoadString(ghInstance, iTitle, szTitle, MAX_PATH)) { pTitle = szTitle; } }
if (LoadString(ghInstance, iMsg, szErrMsg, MAX_PATH*8)) { return (MessageBox(hDlg, szErrMsg, pTitle, iType)); }
return (FALSE); }
////////////////////////////////////////////////////////////////////////////
//
// TransNum
//
// Converts a number string to a dword value (in hex).
//
////////////////////////////////////////////////////////////////////////////
DWORD TransNum(LPTSTR lpsz) { DWORD dw = 0L; TCHAR c;
while (*lpsz) { c = *lpsz++;
if (c >= TEXT('A') && c <= TEXT('F')) { c -= TEXT('A') - 0xa; } else if (c >= TEXT('0') && c <= TEXT('9')) { c -= TEXT('0'); } else if (c >= TEXT('a') && c <= TEXT('f')) { c -= TEXT('a') - 0xa; } else { break; } dw *= 0x10; dw += c; } return (dw); }
////////////////////////////////////////////////////////////////////////////////////
//
// NextCommandArg
//
// pointing to next command argument (TEXT('-') or TEXT('/')
//
////////////////////////////////////////////////////////////////////////////////////
LPTSTR NextCommandArg(LPTSTR lpCmdLine) { LPTSTR strPtr=NULL;
if(!lpCmdLine) { return (strPtr); }
while(*lpCmdLine) { if ((*lpCmdLine == TEXT('-')) || (*lpCmdLine == TEXT('/'))) { // Skip to the character after the '-','/'.
strPtr = lpCmdLine + 1; break; } lpCmdLine++; } return (strPtr); }
////////////////////////////////////////////////////////////////////////////
//
// LoadHive
//
// The caller of this function needs to call UnloadHive() when
// the function succeeds in order to properly release the handle on the
// NTUSER.DAT file.
//
////////////////////////////////////////////////////////////////////////////
HKEY LoadHive(LPCTSTR szProfile, LPCTSTR lpRoot, LPCTSTR lpKeyName, BOOLEAN *lpWasEnabled) { HKEY hKey = NULL; LONG rc = 0L; BOOL bRet = TRUE; TCHAR szKeyName[REGSTR_MAX_VALUE_LENGTH] = {0};
//
// Set the value in the Default User hive.
//
rc = (*pfnRtlAdjustPrivilege)(SE_RESTORE_PRIVILEGE, TRUE, FALSE, lpWasEnabled); if (NT_SUCCESS(rc)) { //
// Load the hive and restore the privilege to its previous state.
//
rc = RegLoadKey(HKEY_USERS, lpRoot, szProfile); (*pfnRtlAdjustPrivilege)(SE_RESTORE_PRIVILEGE, *lpWasEnabled, FALSE, lpWasEnabled);
//
// If the hive loaded properly, set the value.
//
if (NT_SUCCESS(rc)) { //
// Get the temporary key name.
//
//sprintf(szKeyName, "%s\\%s", lpRoot, lpKeyName);
StringCchPrintf(szKeyName, ARRAYSIZE(szKeyName), "%s\\%s", lpRoot, lpKeyName); if ((rc = RegOpenKeyEx( HKEY_USERS, szKeyName, 0L, KEY_READ | KEY_WRITE, &hKey )) == ERROR_SUCCESS) { return (hKey); } else { UnloadHive(lpRoot, lpWasEnabled); return (NULL); } } }
return (NULL); }
////////////////////////////////////////////////////////////////////////////
//
// UnloadHive
//
////////////////////////////////////////////////////////////////////////////
void UnloadHive( LPCTSTR lpRoot, BOOLEAN *lpWasEnabled) { if (NT_SUCCESS((*pfnRtlAdjustPrivilege)( SE_RESTORE_PRIVILEGE, TRUE, FALSE, lpWasEnabled ))) { RegUnLoadKey(HKEY_USERS, lpRoot); (*pfnRtlAdjustPrivilege)( SE_RESTORE_PRIVILEGE, *lpWasEnabled, FALSE, lpWasEnabled ); } }
///////////////////////////////////////////////////////////////////////////////
//
// LoadLibraries
//
// Load libraries specifically used on Windows NTx for the default users case.
//
///////////////////////////////////////////////////////////////////////////////
BOOL LoadLibraries() { //
// Load the userenv.dll library.
//
if (!hUserenvDLL) { hUserenvDLL = LoadLibrary("userenv.dll"); }
//
// Initialize functions from the userenv.dll.
//
if (hUserenvDLL) { //
// Initialize Install function.
//
pfnGetProfilesDirectory = (BOOL (*)(LPSTR, LPDWORD)) GetProcAddress(hUserenvDLL, "GetProfilesDirectoryA"); } else { return (FALSE); }
//
// Load the user32.dll library.
//
if (!hUser32DLL) { hUser32DLL = LoadLibrary("user32.dll"); }
//
// Initialize functions from the user32.dll.
//
if (hUser32DLL) { //
// Initialize Install function.
//
pfnBroadcastSystemMessage = (long (*)(DWORD, LPDWORD, UINT, WPARAM, LPARAM)) GetProcAddress(hUser32DLL, "BroadcastSystemMessageA"); } else { return (FALSE); }
//
// Load the ntdll.dll library.
//
if (!hNtdllDLL) { hNtdllDLL = LoadLibrary("ntdll.dll"); }
//
// Initialize functions from the userenv.dll.
//
if (hNtdllDLL) { //
// Initialize Install function.
//
pfnRtlAdjustPrivilege = (LONG (*)(ULONG, BOOLEAN, BOOLEAN, PBOOLEAN)) GetProcAddress(hNtdllDLL, "RtlAdjustPrivilege"); } else { return (FALSE); }
return (TRUE); }
///////////////////////////////////////////////////////////////////////////////
//
// UnloadLibraries
//
// Unload used libraries.
//
///////////////////////////////////////////////////////////////////////////////
void UnloadLibraries() { //
// Unload the userenv.dll library.
//
if (hUserenvDLL) { FreeLibrary(hUserenvDLL); hUserenvDLL = NULL; pfnGetProfilesDirectory = NULL; }
//
// Unload the user32.dll library.
//
if (hUser32DLL) { FreeLibrary(hUser32DLL); hUser32DLL = NULL; pfnBroadcastSystemMessage = NULL; }
//
// Unload the ntdll.dll library.
//
if (hNtdllDLL) { FreeLibrary(hNtdllDLL); hNtdllDLL = NULL; pfnRtlAdjustPrivilege = NULL; } }
///////////////////////////////////////////////////////////////////////////////
//
// GetDocumentAndSettingsFolder
//
// Return the Document and Settings folder.
//
///////////////////////////////////////////////////////////////////////////////
BOOL GetDocumentAndSettingsFolder(LPSTR buffer) { DWORD cchDir = MAX_PATH;
if (IsWindows9x()) { //
// Not applicable.
//
buffer[0] = '\0'; return (FALSE); } else { //
// Get the directory.
//
if (pfnGetProfilesDirectory) { return ((*pfnGetProfilesDirectory)(buffer, &cchDir)); } }
return (FALSE); }
////////////////////////////////////////////////////////////////////////////
//
// IsValidUserDataFile
//
// Determines if the user data file exists and is accessible.
//
////////////////////////////////////////////////////////////////////////////
BOOL IsValidUserDataFile(LPSTR pFileName) { WIN32_FIND_DATA FindData; HANDLE FindHandle; BOOL bRet; UINT OldMode;
OldMode = SetErrorMode(SEM_FAILCRITICALERRORS);
FindHandle = FindFirstFile(pFileName, &FindData); if (FindHandle == INVALID_HANDLE_VALUE) { bRet = FALSE; } else { FindClose(FindHandle); bRet = TRUE; }
SetErrorMode(OldMode);
return (bRet); }
///////////////////////////////////////////////////////////////////////////////
//
// GetLocaleFromRegistry
//
// Return locale used by a specific user.
//
///////////////////////////////////////////////////////////////////////////////
LCID GetLocaleFromRegistry(HKEY hKey) { HKEY hIntlKey; CHAR szLocale[REGSTR_MAX_VALUE_LENGTH] = {0}; DWORD dwLocale = REGSTR_MAX_VALUE_LENGTH; LCID locale = 0x00000000; //
// Open the appropriate key.
//
if(RegOpenKeyEx( hKey, c_szCPanelIntl, 0, KEY_READ, &hIntlKey) == ERROR_SUCCESS) { //
// Query the value.
//
if( RegQueryValueEx( hIntlKey, c_szLocale, NULL, NULL, szLocale, &dwLocale) == ERROR_SUCCESS) { //
// Convert the string value to hex value.
//
if (szLocale[0] != '\0') { locale = TransNum(szLocale); } }
//
// Close registry handle.
//
RegCloseKey(hIntlKey); }
//
// Return value.
//
return (locale); }
////////////////////////////////////////////////////////////////////////////
//
// GetLocaleFromFile
//
// Gets the Locale for the user data file. The user data file is
// corresponding to the NTUSER.DAT file.
//
////////////////////////////////////////////////////////////////////////////
LCID GetLocaleFromFile(LPSTR szProfile) { HKEY hHive; CHAR szLocale[REGSTR_MAX_VALUE_LENGTH] = {0}; DWORD dwLocale = REGSTR_MAX_VALUE_LENGTH; LCID locale = 0x00000000; BOOLEAN wasEnabled;
//
// Load hive.
//
if ((hHive = LoadHive( szProfile, "TempKey", c_szCPanelIntl, &wasEnabled )) != NULL) { //
// Query the value.
//
if( RegQueryValueEx( hHive, c_szLocale, NULL, NULL, szLocale, &dwLocale) == ERROR_SUCCESS) { //
// Convert the string value to hex value.
//
if (szLocale[0] != '\0') { locale = TransNum(szLocale); } }
//
// Unload hive.
//
RegCloseKey(hHive); UnloadHive("TempKey", &wasEnabled); }
return locale; }
////////////////////////////////////////////////////////////////////////////
//
// RebootTheSystem
//
// This routine enables all privileges in the token, calls ExitWindowsEx
// to reboot the system, and then resets all of the privileges to their
// old state.
//
////////////////////////////////////////////////////////////////////////////
VOID RebootTheSystem() { if (IsWindows9x()) { //
// Enumerate all windows end ask them to close
//
EnumWindows((WNDENUMPROC)EnumWindowsProc, 0);
//
// Exit normally.
//
ExitWindowsEx(EWX_REBOOT, 0); } else { HANDLE Token = NULL; ULONG ReturnLength, Index; PTOKEN_PRIVILEGES NewState = NULL; PTOKEN_PRIVILEGES OldState = NULL; BOOL Result;
Result = OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &Token ); if (Result) { ReturnLength = 4096; NewState = (PTOKEN_PRIVILEGES)LocalAlloc(LPTR, ReturnLength); OldState = (PTOKEN_PRIVILEGES)LocalAlloc(LPTR, ReturnLength); Result = (BOOL)((NewState != NULL) && (OldState != NULL)); if (Result) { Result = GetTokenInformation( Token, // TokenHandle
TokenPrivileges, // TokenInformationClass
NewState, // TokenInformation
ReturnLength, // TokenInformationLength
&ReturnLength ); // ReturnLength
if (Result) { //
// Set the state settings so that all privileges are
// enabled...
//
if (NewState->PrivilegeCount > 0) { for (Index = 0; Index < NewState->PrivilegeCount; Index++) { NewState->Privileges[Index].Attributes = SE_PRIVILEGE_ENABLED; } }
Result = AdjustTokenPrivileges( Token, // TokenHandle
FALSE, // DisableAllPrivileges
NewState, // NewState
ReturnLength, // BufferLength
OldState, // PreviousState
&ReturnLength ); // ReturnLength
if (Result) { ExitWindowsEx(EWX_REBOOT, 0);
AdjustTokenPrivileges( Token, FALSE, OldState, 0, NULL, NULL ); } } } }
if (NewState != NULL) { LocalFree(NewState); } if (OldState != NULL) { LocalFree(OldState); } if (Token != NULL) { CloseHandle(Token); } } }
////////////////////////////////////////////////////////////////////////////
//
// RemoveQuotes
//
// Remove quotes from a string.
//
////////////////////////////////////////////////////////////////////////////
LPSTR RemoveQuotes(LPSTR lpString) { LPSTR strPtr = lpString;
if (lpString && *lpString) { if (*strPtr == '"') { lpString++; strPtr++; }
while (*strPtr) { if (*strPtr == '"') { *strPtr = '\0'; } strPtr++; } }
return (lpString); }
////////////////////////////////////////////////////////////////////////////
//
// EnumWindowsProc
//
// Function used to reboot the system (Windows 9x only).
//
////////////////////////////////////////////////////////////////////////////
BOOL CALLBACK EnumWindowsProc(HWND hwnd, DWORD lParam) { DWORD pid = 0; LRESULT lResult; HANDLE hProcess; DWORD dwResult;
lResult = SendMessageTimeout(hwnd, WM_QUERYENDSESSION, 0, ENDSESSION_LOGOFF, SMTO_ABORTIFHUNG, 2000, (PDWORD_PTR)(&dwResult));
if (lResult) { //
// Application will terminate nicely, so let it.
//
lResult = SendMessageTimeout(hwnd, WM_ENDSESSION, TRUE, ENDSESSION_LOGOFF, SMTO_ABORTIFHUNG, 2000, (PDWORD_PTR)(&dwResult)); } else // You have to take more forceful measures.
{ //
// Get the ProcessId for this window.
//
GetWindowThreadProcessId(hwnd, &pid); //
// Open the process with all access.
//
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); //
// Terminate the process.
//
TerminateProcess(hProcess, 0); } //
// Continue the enumeration.
//
return TRUE; }
|