You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1009 lines
26 KiB
1009 lines
26 KiB
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
|