1159 lines
33 KiB
C++
1159 lines
33 KiB
C++
#include "private.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "hklhelp.h"
|
|
|
|
// Forward decl.
|
|
POSVERSIONINFO GetVersionInfo();
|
|
BOOL WINAPI IsMemphisOrME();
|
|
BOOL WINAPI IsWin95();
|
|
BOOL WINAPI IsNT();
|
|
BOOL WINAPI IsNT4();
|
|
BOOL WINAPI IsNT5orUpper();
|
|
BOOL IsHydra();
|
|
#if 0
|
|
BOOL SetRegKeyAccessRight(HKEY hKey);
|
|
#endif
|
|
PSID MyCreateSid(DWORD dwSubAuthority);
|
|
VOID FreeSecurityAttributes(PSECURITY_ATTRIBUTES psa);
|
|
|
|
// IME 2002 main module
|
|
#define SZMODULENAME_MAIN "imekr.ime"
|
|
|
|
// IME Main HKLM Reg
|
|
#define SZIMEREG_MAIN_ROOT "Software\\Microsoft\\IMEKR\\6.0"
|
|
#define SZIMEREG_MAIN_ROOT_MIG SZIMEREG_MAIN_ROOT"\\MigrateUser"
|
|
|
|
|
|
// Kor TIP profile reg
|
|
#define SZTIPREG_LANGPROFILE "SOFTWARE\\Microsoft\\CTF\\TIP\\{766A2C14-B226-4fd6-B52A-867B3EBF38D2}\\LanguageProfile\\0x00000412"
|
|
|
|
#define MAJORVER "6.0"
|
|
#define IME_REGISTRY_LATEST_VERSION "Software\\Microsoft\\IMEKR" //The latest version of IME installed in the system
|
|
//will always be stored at HKLM\Software\Microsoft\IMEKR
|
|
//even if it's system IME.
|
|
|
|
// Preperty names
|
|
#define PROPERTYNAME_QueryPreInstallStatus "QueryPreInstallStatus.CC794FB4_4D43_40AA_A417_4A8D938D3D69"
|
|
#define PROPERTYNAME_CheckOnlyOneIME "CheckOnlyOneIME.CC794FB4_4D43_40AA_A417_4A8D938D3D69"
|
|
#define PROPERTYNAME_RemoveFromPreload "CustomActionData"
|
|
#define PROPERTYNAME_ImmUninstallIME "CustomActionData"
|
|
#define PROPERTYNAME_RBImmInstallIME "CustomActionData"
|
|
#define PROPERTYNAME_RBSetDefaultIME "CustomActionData"
|
|
#define PROPERTYNAME_ImmInstallIME "CustomActionData"
|
|
#define PROPERTYNAME_SetDefaultIME "CustomActionData"
|
|
|
|
|
|
// Private helper functions
|
|
static HKL GenerateProperFreeHKL();
|
|
static BOOL IsPerUser9x();
|
|
|
|
/*---------------------------------------------------------------------------
|
|
QueryPreInstallStatus
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT WINAPI QueryPreInstallStatus(MSIHANDLE hSession)
|
|
{
|
|
CHAR szBuffer[100];
|
|
DWORD dwBuffer = sizeof(szBuffer);
|
|
|
|
if (MsiGetProperty(hSession, PROPERTYNAME_QueryPreInstallStatus, szBuffer, &dwBuffer) == ERROR_SUCCESS)
|
|
{
|
|
HKL hKL;
|
|
HKL hCurrentDefaultHKL;
|
|
CHAR szCurrentDefaultHKL[10];
|
|
DWORD dwKorKL = 0x00000412;
|
|
DWORD dwKLMask = 0x0000FFFF;
|
|
DWORD dwCurHKL, dwKL;
|
|
|
|
hKL = GetHKLfromHKLM(szBuffer);
|
|
|
|
// If imekr.ime exist
|
|
if (hKL)
|
|
{
|
|
MsiSetProperty(hSession, "IMEAlreadyInstalled.CC794FB4_4D43_40AA_A417_4A8D938D3D69", "1");
|
|
MsiSetProperty(hSession, "RBImmInstallIME.CC794FB4_4D43_40AA_A417_4A8D938D3D69", "");
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL,"IME2002 has already been registerd.","DEBUG",MB_OK);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
MsiSetProperty(hSession, "RBImmInstallIME.CC794FB4_4D43_40AA_A417_4A8D938D3D69", szBuffer);
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL,"IME2002 has not been registerd. Should be removed in RollBack.","DEBUG",MB_OK);
|
|
#endif
|
|
}
|
|
|
|
SystemParametersInfo(SPI_GETDEFAULTINPUTLANG, 0, &hCurrentDefaultHKL, 0);
|
|
wsprintf(szCurrentDefaultHKL,"%08x",hCurrentDefaultHKL);
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL,szCurrentDefaultHKL,"Current Default HKL",MB_OK);
|
|
#endif
|
|
|
|
|
|
dwCurHKL = *((DWORD *) &hCurrentDefaultHKL);
|
|
dwKL = (dwCurHKL & dwKLMask);
|
|
|
|
// only set as default when the current hKL is Korean.
|
|
if (dwKorKL != dwKL)
|
|
{
|
|
MsiSetProperty(hSession, "NotSetDefault.CC794FB4_4D43_40AA_A417_4A8D938D3D69","1");
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL, "Default KBL was not Korean","QueryPreInstallStatus",MB_OK);
|
|
#endif
|
|
}
|
|
|
|
MsiSetProperty(hSession, "RBSetDefaultIME.CC794FB4_4D43_40AA_A417_4A8D938D3D69", szCurrentDefaultHKL);
|
|
}
|
|
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CheckOnlyOneIME
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT WINAPI CheckOnlyOneIME(MSIHANDLE hSession)
|
|
{
|
|
CHAR szBuffer[100];
|
|
DWORD dwBuffer=sizeof(szBuffer);
|
|
|
|
if (MsiGetProperty(hSession, PROPERTYNAME_CheckOnlyOneIME, szBuffer, &dwBuffer) == ERROR_SUCCESS)
|
|
{
|
|
if (GetKeyboardLayoutList(0,NULL) == 1)
|
|
{
|
|
HKL TheHKL;
|
|
|
|
if (GetKeyboardLayoutList(1,&TheHKL) == 1)
|
|
{
|
|
if (GetHKLfromHKLM(szBuffer) == TheHKL)
|
|
MsiSetProperty(hSession, "OnlyOneIME.CC794FB4_4D43_40AA_A417_4A8D938D3D69", "1");
|
|
}
|
|
}
|
|
}
|
|
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CheckIMM
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT WINAPI CheckIMM(MSIHANDLE hSession)
|
|
{
|
|
// If non Korean Win9x platform, we couldn't install system IMM32 IME since there is no IMM support.
|
|
if (!IsNT5orUpper() && PRIMARYLANGID(GetSystemDefaultLCID()) != LANG_KOREAN)
|
|
{
|
|
MsiSetProperty(hSession, "INSTALLIME.CC794FB4_4D43_40AA_A417_4A8D938D3D69", "0");
|
|
}
|
|
else
|
|
{
|
|
MsiSetProperty(hSession, "INSTALLIME.CC794FB4_4D43_40AA_A417_4A8D938D3D69", "1");
|
|
}
|
|
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
IsPerUser9x
|
|
---------------------------------------------------------------------------*/
|
|
static BOOL IsPerUser9x()
|
|
{
|
|
BOOL fResult = fFalse;
|
|
HKEY hKey;
|
|
DWORD dwMultiUser;
|
|
DWORD dwBufferSize = sizeof(dwMultiUser);
|
|
|
|
if (IsNT())
|
|
return(fFalse);
|
|
|
|
if (ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, "Network\\Logon", &hKey))
|
|
{
|
|
// Fail to open network reg. That means single environment immeriately.
|
|
if (ERROR_SUCCESS == RegQueryValueEx( hKey, "UserProfiles", NULL, NULL, (unsigned char *)&dwMultiUser, &dwBufferSize))
|
|
{
|
|
// Fail to open UserProfiles. That means single environment immeriately.
|
|
if(1 == dwMultiUser)
|
|
{
|
|
// HKEY_LOCAL_MACHINE\Network\Logon\UserProfiles = 1 means multiuser
|
|
fResult = fTrue;
|
|
}
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
return(fResult);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
CheckPerUserWin9x
|
|
|
|
Check if multiuser using Win9x platform.
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT WINAPI CheckPerUserWin9x(MSIHANDLE hSession)
|
|
{
|
|
HKEY hKey;
|
|
DWORD dwMultiUser, dwAllowRemove;
|
|
DWORD dwBufferSize = sizeof(dwMultiUser);
|
|
BOOL fAllowRemove = fTrue;
|
|
|
|
if (!IsNT())
|
|
{
|
|
if(IsPerUser9x())
|
|
{
|
|
fAllowRemove = fFalse;
|
|
}
|
|
}
|
|
|
|
if (fAllowRemove)
|
|
MsiSetProperty(hSession, "PerUserWin9x.CC794FB4_4D43_40AA_A417_4A8D938D3D69", "0");
|
|
else
|
|
MsiSetProperty(hSession, "PerUserWin9x.CC794FB4_4D43_40AA_A417_4A8D938D3D69", "1");
|
|
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
RemoveFromPreload
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT WINAPI RemoveFromPreload(MSIHANDLE hSession)
|
|
{
|
|
CHAR szBuffer[100];
|
|
DWORD dwBuffer = sizeof(szBuffer);
|
|
|
|
if (MsiGetProperty(hSession, PROPERTYNAME_RemoveFromPreload, szBuffer, &dwBuffer) == ERROR_SUCCESS)
|
|
{
|
|
HKL hKL = GetHKLfromHKLM(szBuffer);
|
|
|
|
if (hKL)
|
|
{
|
|
HKLHelpRemoveFromPreload(HKEY_CURRENT_USER, hKL);
|
|
RegFlushKey(HKEY_CURRENT_USER);
|
|
|
|
hKL = GetDefaultIMEFromHKCU(HKEY_CURRENT_USER);
|
|
SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, 0, (HKL*)&hKL, SPIF_SENDCHANGE);
|
|
}
|
|
}
|
|
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
|
|
//
|
|
// C l e a n U p P r e l o a d
|
|
//
|
|
// - Remove given IME2002 HKL from preload under given hKeyCU. hKeyCU is usually HKEY_CURRENT_USER or HKEY_USERS\.Default.
|
|
// - Remove all old MS-IME, too. This is for clean up. Practically we don't expect such HKL exist in preload.
|
|
// - If default keyboard layout was Satori, add latest (but older than Satori) MS-IME and make it default keyboard layout.
|
|
//
|
|
static void CleanUpPreload(HKEY hKeyCU, HKL hKLIme2002)
|
|
{
|
|
BOOL fMSIMEWasDefault = fFalse;
|
|
HKL hKLOldMSIME = NULL;
|
|
HKL hKLLatestMSIME = NULL;
|
|
HKL hklDefault;
|
|
|
|
hklDefault = GetDefaultIMEFromHKCU(hKeyCU);
|
|
|
|
if (hKLIme2002 == hklDefault)
|
|
fMSIMEWasDefault = TRUE;
|
|
|
|
HKLHelpRemoveFromPreload(hKeyCU, hKLIme2002);
|
|
|
|
// Win95 IME
|
|
hKLOldMSIME = GetHKLfromHKLM("msime95.ime");
|
|
hKLLatestMSIME = hKLOldMSIME;
|
|
if (hKLOldMSIME)
|
|
{
|
|
if (hklDefault == hKLOldMSIME)
|
|
fMSIMEWasDefault = fTrue;
|
|
|
|
if (HKLHelpExistInPreload(hKeyCU, hKLOldMSIME))
|
|
{
|
|
HKLHelpRemoveFromPreload(hKeyCU, hKLOldMSIME);
|
|
UnloadKeyboardLayout(hKLOldMSIME);
|
|
}
|
|
}
|
|
|
|
// NT4 IME
|
|
hKLOldMSIME = GetHKLfromHKLM("msime95k.ime");
|
|
if (hKLOldMSIME)
|
|
{
|
|
if (hklDefault == hKLOldMSIME)
|
|
fMSIMEWasDefault = fTrue;
|
|
|
|
if (HKLHelpExistInPreload(hKeyCU, hKLOldMSIME))
|
|
{
|
|
HKLHelpRemoveFromPreload(hKeyCU, hKLOldMSIME);
|
|
UnloadKeyboardLayout(hKLOldMSIME);
|
|
}
|
|
hKLLatestMSIME = hKLOldMSIME;
|
|
}
|
|
|
|
// Win98, ME, NT4 SP6 & W2K IME
|
|
hKLOldMSIME = GetHKLfromHKLM("imekr98u.ime");
|
|
if (hKLOldMSIME)
|
|
{
|
|
if (hklDefault == hKLOldMSIME)
|
|
fMSIMEWasDefault = fTrue;
|
|
|
|
if (HKLHelpExistInPreload(hKeyCU, hKLOldMSIME))
|
|
{
|
|
HKLHelpRemoveFromPreload(hKeyCU, hKLOldMSIME);
|
|
UnloadKeyboardLayout(hKLOldMSIME);
|
|
}
|
|
hKLLatestMSIME = hKLOldMSIME;
|
|
}
|
|
|
|
// If IME2002 was default, we should enable latest Kor IME.
|
|
if (fMSIMEWasDefault && hKLLatestMSIME)
|
|
HKLHelpSetDefaultKeyboardLayout(hKeyCU, hKLLatestMSIME, TRUE/*fSetDefault*/);
|
|
}
|
|
|
|
// !!! TEMPORARY SOLUTION START !!!
|
|
static
|
|
BOOL KYFileExist(LPCSTR szFilePath)
|
|
{
|
|
HANDLE hFile;
|
|
|
|
if(INVALID_HANDLE_VALUE != (hFile = CreateFileA(szFilePath, GENERIC_READ,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL))){
|
|
CloseHandle(hFile);
|
|
return(TRUE);
|
|
}
|
|
return(FALSE);
|
|
}
|
|
|
|
static
|
|
void CatBackslashIfNeededA(LPSTR szPath)
|
|
{
|
|
if('\\'!=szPath[lstrlenA(szPath)-1]){
|
|
lstrcatA(szPath, "\\");
|
|
}
|
|
}
|
|
// !!! TEMPORARY SOLUTION END !!!
|
|
|
|
/*---------------------------------------------------------------------------
|
|
ImmUninstallIME
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT WINAPI ImmUninstallIME(MSIHANDLE hSession)
|
|
{
|
|
CHAR szBuffer[100];
|
|
DWORD dwBuffer = sizeof(szBuffer);
|
|
HKEY hKLOldMSIME;
|
|
HKEY hKey;
|
|
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL, "ImmUninstallIME", "Enter", MB_OK);
|
|
#endif
|
|
|
|
if (MsiGetProperty(hSession, PROPERTYNAME_ImmUninstallIME, szBuffer, &dwBuffer) == ERROR_SUCCESS)
|
|
{
|
|
HKL hKL = GetHKLfromHKLM(szBuffer);
|
|
|
|
if (hKL)
|
|
{
|
|
CleanUpPreload(HKEY_CURRENT_USER, hKL);
|
|
|
|
// In single user Win9x, HKCU also changes HKU\.Default
|
|
if (IsPerUser9x())
|
|
{
|
|
HKEY hKey;
|
|
// Remove from HKU\.default for default setting
|
|
if (RegOpenKeyEx(HKEY_USERS, TEXT(".Default"), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
|
{
|
|
CleanUpPreload(hKey, hKL);
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
|
|
// Remove from HKLM
|
|
HKLHelpRemoveFromControlSet(hKL);
|
|
|
|
// Remove Substitute HKL value
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, SZTIPREG_LANGPROFILE, 0, KEY_ALL_ACCESS, &hKey))
|
|
{
|
|
CHAR szSubKeyName[MAX_PATH];
|
|
DWORD dwIndex;
|
|
HKEY hSubKey;
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL, "Removing Substitute HKL value", "ImmUninstallIME",MB_OK);
|
|
#endif
|
|
dwIndex = 0;
|
|
while (ERROR_NO_MORE_ITEMS != RegEnumKey(hKey, dwIndex, szSubKeyName, MAX_PATH))
|
|
{
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL, szSubKeyName, "ImmUninstallIME - enumerating subkeys", MB_OK);
|
|
#endif
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(hKey,szSubKeyName,0,KEY_ALL_ACCESS, &hSubKey))
|
|
{
|
|
RegDeleteValue(hSubKey,"SubstituteLayout");
|
|
RegCloseKey(hSubKey);
|
|
}
|
|
dwIndex++;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL, "ImmUninstallIME", "Success", MB_OK);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
RBImmInstallIME
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT WINAPI RBImmInstallIME(MSIHANDLE hSession)
|
|
{
|
|
CHAR szBuffer[100];
|
|
DWORD dwBuffer = sizeof(szBuffer);
|
|
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL,"RBImmInstallIME","Enter",MB_OK);
|
|
#endif
|
|
|
|
if (MsiGetProperty(hSession, PROPERTYNAME_RBImmInstallIME, szBuffer, &dwBuffer) == ERROR_SUCCESS)
|
|
{
|
|
if (dwBuffer)
|
|
{
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL,szBuffer,"RollBack: Remove HKL from ControlSet",MB_OK);
|
|
#endif
|
|
HKL hKL = GetHKLfromHKLM(szBuffer);
|
|
if (hKL)
|
|
{
|
|
HKLHelpRemoveFromPreload(HKEY_CURRENT_USER, hKL);
|
|
HKLHelpRemoveFromControlSet(hKL);
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL,"RBImmInstallIME","Success",MB_OK);
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
RBSetDefaultIME
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT WINAPI RBSetDefaultIME(MSIHANDLE hSession)
|
|
{
|
|
CHAR szBuffer[100];
|
|
DWORD dwBuffer = sizeof(szBuffer);
|
|
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL, "RBSetDefault", "Enter", MB_OK);
|
|
#endif
|
|
|
|
if (MsiGetProperty(hSession, PROPERTYNAME_RBSetDefaultIME, szBuffer, &dwBuffer) == ERROR_SUCCESS)
|
|
{
|
|
HKL hKL;
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL, szBuffer, "RollBack: Set Default IME to...", MB_OK);
|
|
#endif
|
|
sscanf(szBuffer, "%08x", &hKL);
|
|
if (hKL)
|
|
{
|
|
HKLHelpSetDefaultKeyboardLayout(HKEY_CURRENT_USER, hKL, TRUE/*fSetDefault*/);
|
|
RegFlushKey(HKEY_CURRENT_USER);
|
|
SetDefaultKeyboardLayoutForDefaultUser(hKL);
|
|
}
|
|
}
|
|
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// G e n e r a t e P r o p e r t F r e e H K L
|
|
//
|
|
// Search e0xx0412 HKL in HKLM\...\Keyboard Layouts where xx >= 20.
|
|
// Returns first free HKL
|
|
//
|
|
// Stolen from Satori code.
|
|
HKL GenerateProperFreeHKL(void)
|
|
{
|
|
HKL hKLCandidate = 0;
|
|
CHAR szLayoutString[100];
|
|
DWORD dwLayoutString;
|
|
|
|
for (UINT i=0x20; i<0x100; i++)
|
|
{
|
|
|
|
hKLCandidate = (HKL)(DWORD)((DWORD)0xe0 << 24 | i << 16 | 0x0412);
|
|
|
|
dwLayoutString = sizeof(szLayoutString);
|
|
szLayoutString[0] = 0;
|
|
// Get "Layout Text"
|
|
HKLHelpGetLayoutString(hKLCandidate, szLayoutString, &dwLayoutString);
|
|
|
|
if (szLayoutString[0] == 0)
|
|
{
|
|
// HKL not used is found.
|
|
break;
|
|
}
|
|
}
|
|
|
|
return(hKLCandidate);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
ImmInstallIME
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT WINAPI CSImmInstallIME(MSIHANDLE hSession)
|
|
{
|
|
TCHAR szBuffer[100], szIMEFullPath[MAX_PATH];
|
|
DWORD dwBuffer=sizeof(szBuffer);
|
|
HKEY hKey;
|
|
HKL hKLIME2002;
|
|
CHAR szSubKeyName[MAX_PATH], szHKL[MAX_PATH];
|
|
DWORD dwIndex;
|
|
HKEY hHKCU;
|
|
|
|
if (!IsNT5orUpper() && (PRIMARYLANGID(GetSystemDefaultLCID()) != LANG_KOREAN))
|
|
return(ERROR_SUCCESS);
|
|
|
|
if (MsiGetProperty(hSession, PROPERTYNAME_ImmInstallIME, szBuffer, &dwBuffer) == ERROR_SUCCESS)
|
|
{
|
|
for (LPSTR CurPtr = szBuffer; 0!=*CurPtr; CurPtr=CharNext(CurPtr))
|
|
{
|
|
if (*CurPtr == ',')
|
|
{
|
|
*CurPtr=0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (GetSystemDirectory(szIMEFullPath, sizeof(szIMEFullPath)))
|
|
{
|
|
lstrcat(szIMEFullPath, "\\");
|
|
lstrcat(szIMEFullPath, szBuffer);
|
|
|
|
hKLIME2002 = GetHKLfromHKLM(SZMODULENAME_MAIN);
|
|
|
|
if (hKLIME2002 == NULL)
|
|
hKLIME2002 = GenerateProperFreeHKL();
|
|
|
|
// Workaround for NT5 #155950
|
|
HKLHelpRegisterIMEwithForcedHKL(hKLIME2002, szBuffer, CurPtr + 1);
|
|
|
|
if (ImmInstallIME(szIMEFullPath, CurPtr+1))
|
|
{
|
|
#ifdef SETUP_DBG
|
|
TCHAR hoge[100];
|
|
wsprintf(hoge,"%x", ImmInstallIME(szIMEFullPath, CurPtr+1));
|
|
MessageBox(NULL, hoge, "ImmInstallIME", MB_OK);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL, "ImmInstallIME failed", "DEBUG", MB_OK);
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add Substitute HKL value to the registry
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, SZTIPREG_LANGPROFILE, 0, KEY_ALL_ACCESS, &hKey))
|
|
{
|
|
HKEY hSubKey;
|
|
HKL hkl;
|
|
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL, "Adding Substitute HKL value", "ImmInstallIME",MB_OK);
|
|
#endif
|
|
|
|
hkl = GetHKLfromHKLM(SZMODULENAME_MAIN);
|
|
|
|
wsprintf(szHKL, "0x%x", hkl);
|
|
dwIndex = 0;
|
|
|
|
while (ERROR_NO_MORE_ITEMS != RegEnumKey(hKey, dwIndex, szSubKeyName, MAX_PATH))
|
|
{
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL, szSubKeyName, "ImmInstallIME - enumerating subkeys", MB_OK);
|
|
#endif
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(hKey,szSubKeyName,0,KEY_ALL_ACCESS, &hSubKey))
|
|
{
|
|
RegSetValueEx(hSubKey, "SubstituteLayout", 0, REG_SZ, (BYTE *)szHKL, (sizeof(CHAR)*lstrlen(szHKL)));
|
|
RegCloseKey(hSubKey);
|
|
}
|
|
dwIndex++;
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
// Remove from preload if IME2000 is not latest ime.
|
|
BOOL fLatest = TRUE;
|
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, IME_REGISTRY_LATEST_VERSION, 0, KEY_READ, &hKey)==ERROR_SUCCESS)
|
|
{
|
|
if(ERROR_SUCCESS == RegQueryValueEx(hKey, "version", NULL, NULL, (BYTE *)szBuffer, &dwBuffer))
|
|
{
|
|
if(0!=lstrcmpi(szBuffer, MAJORVER))
|
|
//version different.
|
|
fLatest = FALSE;
|
|
}
|
|
else
|
|
fLatest = FALSE; //version reg didn't exist
|
|
RegCloseKey(hKey);
|
|
}
|
|
else
|
|
fLatest = FALSE; //version reg didn't exist
|
|
|
|
#ifdef SETUP_DBG
|
|
TCHAR szLog[100];
|
|
wsprintf(szLog,"fLatest == %x, szBuffer = %s", fLatest, szBuffer);
|
|
|
|
MessageBox(NULL, "CSImmInstallIME", szLog, MB_OK);
|
|
#endif
|
|
|
|
if (!fLatest)
|
|
{
|
|
HKL hKL=GetHKLfromHKLM(SZMODULENAME_MAIN);
|
|
if (hKL != 0)
|
|
{
|
|
if(HKLHelpExistInPreload(HKEY_CURRENT_USER, hKL))
|
|
HKLHelpRemoveFromPreload(HKEY_CURRENT_USER, hKL);
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
// This seems not working for all users.
|
|
// Do it imekrmig.exe instead.
|
|
// Reset "Show Status" value of every user's "HKEY_CURRENT_USER\Control Panel\Input Method"
|
|
for (dwIndex=0; cbSubKeyName=MAX_PATH, RegEnumKeyEx(HKEY_USERS, dwIndex, szSubKeyName, &cbSubKeyName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; dwIndex++)
|
|
{
|
|
lstrcat(szSubKeyName, "\\Control Panel\\Input Method");
|
|
lstrcpy(szHKL, "1");
|
|
|
|
if (RegOpenKeyEx(HKEY_USERS, szSubKeyName, 0, KEY_ALL_ACCESS, &hHKCU) == ERROR_SUCCESS)
|
|
{
|
|
RegSetValueEx(hHKCU, "Show Status", 0, REG_SZ, (BYTE *)szHKL, (sizeof(CHAR)*lstrlen(szHKL)));
|
|
RegCloseKey(hHKCU);
|
|
}
|
|
}
|
|
#endif
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
SetDefaultIME
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT WINAPI SetDefaultIME(MSIHANDLE hSession)
|
|
{
|
|
CHAR szBuffer[100];
|
|
DWORD dwBuffer = sizeof(szBuffer);
|
|
HKEY hKey;
|
|
BOOL fNewerVerExist = TRUE;
|
|
|
|
// only set this ime to default if its the latest ime in the system.
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, IME_REGISTRY_LATEST_VERSION, 0, KEY_READ, &hKey))
|
|
{
|
|
if (RegQueryValueEx(hKey, "version", NULL, NULL, (BYTE *)szBuffer, &dwBuffer) == ERROR_SUCCESS)
|
|
{
|
|
if (lstrcmpi(szBuffer, MAJORVER) != 0)
|
|
fNewerVerExist = FALSE;
|
|
}
|
|
else
|
|
fNewerVerExist = FALSE; //version reg didn't exist
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
else
|
|
fNewerVerExist = FALSE; //version reg didn't exist
|
|
|
|
#ifdef SETUP_DBG
|
|
TCHAR szLog[100];
|
|
wsprintf(szLog,"fNewerVerExist = %d", fNewerVerExist);
|
|
|
|
MessageBox(NULL, "SetDefaultIME", szLog, MB_OK);
|
|
#endif
|
|
|
|
if (MsiGetProperty(hSession, PROPERTYNAME_SetDefaultIME, szBuffer, &dwBuffer) == ERROR_SUCCESS)
|
|
{
|
|
HKL hKL = GetHKLfromHKLM(szBuffer);
|
|
|
|
// If newer version exist and
|
|
if (!fNewerVerExist)
|
|
{
|
|
if(HKLHelpExistInPreload(HKEY_CURRENT_USER, hKL))
|
|
HKLHelpRemoveFromPreload(HKEY_CURRENT_USER, hKL);
|
|
|
|
return (ERROR_SUCCESS);
|
|
}
|
|
|
|
if (hKL)
|
|
{
|
|
HKLHelpSetDefaultKeyboardLayout(HKEY_CURRENT_USER, hKL, TRUE/*fSetDefault*/);
|
|
RegFlushKey(HKEY_CURRENT_USER);
|
|
SetDefaultKeyboardLayoutForDefaultUser(hKL);
|
|
}
|
|
}
|
|
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
GetSIDList
|
|
Gets all users' SID and list that in the reg for migration
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT WINAPI GetSIDList(MSIHANDLE hSession)
|
|
{
|
|
HKEY hKey, hUserList;
|
|
DWORD i, cbName;
|
|
BOOL fNoMoreSID = FALSE;
|
|
CHAR szName[500];
|
|
|
|
if(IsNT())
|
|
{
|
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
|
|
{
|
|
|
|
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, SZIMEREG_MAIN_ROOT_MIG, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hUserList, NULL) == ERROR_SUCCESS)
|
|
{
|
|
for (i=0; !fNoMoreSID; i++)
|
|
{
|
|
cbName = 500;
|
|
|
|
if (RegEnumKeyEx(hKey, i, szName, &cbName, NULL, NULL, NULL, NULL) == ERROR_NO_MORE_ITEMS)
|
|
fNoMoreSID = TRUE;
|
|
else
|
|
{
|
|
// Write this user profile to HKLM SZIMEREG_MAIN_ROOT MigrateUser
|
|
RegSetValueEx(hUserList, szName, 0, REG_SZ, NULL, 0);
|
|
}
|
|
}
|
|
|
|
#if 0 // We set this at lock permission table in MSM instead.
|
|
// Give full access to all users for migrate key. IMEKRMIG.EXE will remove SID entry for each user when they logon.
|
|
SetRegKeyAccessRight(hUserList);
|
|
#endif
|
|
RegCloseKey(hUserList);
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Check whether this is a per-user or per-machine installation
|
|
// (Win9x profile on-start menu not shared, Win98 single user env.)
|
|
TCHAR szAllUsers[MAX_PATH];
|
|
DWORD dwBuffer = MAX_PATH;
|
|
if (ERROR_SUCCESS == MsiGetProperty(hSession, TEXT("ALLUSERS"), szAllUsers, &dwBuffer))
|
|
{
|
|
if((szAllUsers[0] == '0')||(dwBuffer == 0)) // if ALLUSERS == 0, (i.e. per-user installation)
|
|
return (ERROR_SUCCESS);
|
|
}
|
|
|
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ProfileList",0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
|
|
{
|
|
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, SZIMEREG_MAIN_ROOT_MIG, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hUserList, NULL) == ERROR_SUCCESS)
|
|
{
|
|
for (i=0; !fNoMoreSID; i++)
|
|
{
|
|
cbName = 500;
|
|
|
|
if (RegEnumKeyEx(hKey, i, szName, &cbName, NULL, NULL, NULL, NULL) == ERROR_NO_MORE_ITEMS)
|
|
fNoMoreSID = TRUE;
|
|
else
|
|
RegSetValueEx(hUserList, szName, 0, REG_SZ, NULL, 0);
|
|
}
|
|
RegCloseKey(hUserList);
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
}
|
|
|
|
return (ERROR_SUCCESS);
|
|
}
|
|
|
|
|
|
HRESULT WINAPI CAScheduleReboot(MSIHANDLE hSession)
|
|
{
|
|
MsiDoAction(hSession, TEXT("ScheduleReboot"));
|
|
|
|
return(ERROR_SUCCESS);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
IMESetLatestVersion
|
|
Sets the latest version reg (HKLM\Software\Microsoft\IMEKR)
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT WINAPI IMESetLatestVersion(MSIHANDLE hSession)
|
|
{
|
|
HKEY hKey;
|
|
float flInstalledVersion, flVersion;
|
|
CHAR szVersion[MAX_PATH];
|
|
DWORD cbVersion = MAX_PATH;
|
|
|
|
if(ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, IME_REGISTRY_LATEST_VERSION, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL))
|
|
{
|
|
if(ERROR_SUCCESS == RegQueryValueEx(hKey, "version", NULL, NULL, (BYTE *)szVersion, &cbVersion))
|
|
{
|
|
flInstalledVersion = (float)atof(szVersion);
|
|
flVersion = (float)atof(MAJORVER);
|
|
|
|
if(flVersion < flInstalledVersion)
|
|
return (ERROR_SUCCESS);
|
|
}
|
|
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL, "IMESetLatestVersion", MAJORVER,MB_OK);
|
|
#endif
|
|
RegSetValueEx(hKey, "version", 0, REG_SZ, (BYTE *)MAJORVER, lstrlen(MAJORVER) * sizeof(TCHAR));
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
return (ERROR_SUCCESS);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
GetLatestVersionIME
|
|
---------------------------------------------------------------------------*/
|
|
void GetLatestVersionIME(HKEY hKey, LPTSTR szLatestVer, LPCTSTR szIgnoreVer)
|
|
{
|
|
DWORD dwIndex = 0;
|
|
CHAR szVersion[MAX_PATH];
|
|
DWORD cbVersion = MAX_PATH;
|
|
|
|
if (hKey)
|
|
{
|
|
RegQueryValueEx(hKey, "Version", NULL, NULL, (BYTE *)szVersion, &cbVersion);
|
|
if ((atof(szVersion) > atof(szLatestVer)) && (lstrcmpi(szVersion, szIgnoreVer) != 0))
|
|
lstrcpy(szLatestVer, szVersion);
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------
|
|
IMERestoreLatestVersion
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT WINAPI IMERestoreLatestVersion(MSIHANDLE hSession)
|
|
{
|
|
HKEY hKey;
|
|
CHAR szLatestVer[MAX_PATH];
|
|
BOOL fLatest = TRUE;
|
|
DWORD cbLatestVer = MAX_PATH;
|
|
|
|
//No need to anything if current version < version in the reg.
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\IMEKR", 0, KEY_READ, &hKey))
|
|
{
|
|
if(ERROR_SUCCESS == RegQueryValueEx(hKey, "version", NULL, NULL, (BYTE *)szLatestVer, &cbLatestVer))
|
|
{
|
|
if(atof(szLatestVer) > atof(MAJORVER))
|
|
fLatest = FALSE;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
if (!fLatest)
|
|
return ERROR_SUCCESS;
|
|
|
|
// init szLatestVer
|
|
lstrcpy(szLatestVer, "0.0");
|
|
|
|
// Get latest system IME version
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\IME\\IMEKR",0, KEY_READ, &hKey))
|
|
{
|
|
GetLatestVersionIME(hKey, szLatestVer, MAJORVER);
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
// Get latest app IME version
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, IME_REGISTRY_LATEST_VERSION, 0, KEY_READ, &hKey))
|
|
{
|
|
GetLatestVersionIME(hKey, szLatestVer, MAJORVER);
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
#ifdef SETUP_DBG
|
|
MessageBox(NULL, "IMERestoreLatestVersion", szLatestVer, MB_OK);
|
|
#endif
|
|
|
|
// if ime version other than MAJORVER was found, write that value to the registry.
|
|
if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, IME_REGISTRY_LATEST_VERSION, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL))
|
|
{
|
|
if (lstrcmpi(szLatestVer, "0.0") == 0)
|
|
RegDeleteValue(hKey, "version");
|
|
else
|
|
RegSetValueEx(hKey, "version", 0, REG_SZ, (BYTE *)szLatestVer, ((lstrlen(szLatestVer)+1) * sizeof(TCHAR)));
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
return (ERROR_SUCCESS);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Private utility functions
|
|
//
|
|
|
|
POSVERSIONINFO GetVersionInfo()
|
|
{
|
|
static BOOL fFirstCall = TRUE;
|
|
static OSVERSIONINFO os;
|
|
|
|
if ( fFirstCall ) {
|
|
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
if ( GetVersionEx( &os ) ) {
|
|
fFirstCall = FALSE;
|
|
}
|
|
}
|
|
return &os;
|
|
}
|
|
|
|
BOOL WINAPI IsMemphisOrME()
|
|
{
|
|
BOOL fResult;
|
|
fResult = (GetVersionInfo()->dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
|
|
(GetVersionInfo()->dwMajorVersion >= 4) &&
|
|
(GetVersionInfo()->dwMinorVersion >= 10);
|
|
|
|
return fResult;
|
|
}
|
|
|
|
BOOL WINAPI IsWin95()
|
|
{
|
|
BOOL fResult;
|
|
fResult = (GetVersionInfo()->dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
|
|
(GetVersionInfo()->dwMajorVersion == 4) &&
|
|
(GetVersionInfo()->dwMinorVersion < 10);
|
|
|
|
return fResult;
|
|
}
|
|
|
|
BOOL WINAPI IsNT()
|
|
{
|
|
BOOL fResult;
|
|
fResult = (GetVersionInfo()->dwPlatformId == VER_PLATFORM_WIN32_NT);
|
|
|
|
return fResult;
|
|
}
|
|
|
|
BOOL WINAPI IsNT4()
|
|
{
|
|
BOOL fResult;
|
|
fResult = (GetVersionInfo()->dwPlatformId == VER_PLATFORM_WIN32_NT) &&
|
|
(GetVersionInfo()->dwMajorVersion == 4);
|
|
|
|
return fResult;
|
|
}
|
|
|
|
BOOL WINAPI IsNT5orUpper()
|
|
{
|
|
BOOL fResult;
|
|
fResult = (GetVersionInfo()->dwPlatformId == VER_PLATFORM_WIN32_NT) &&
|
|
(GetVersionInfo()->dwMajorVersion >= 5);
|
|
|
|
return fResult;
|
|
}
|
|
|
|
BOOL IsHydra()
|
|
{
|
|
static DWORD fTested = fFalse, fHydra = fFalse;
|
|
HKEY hKey;
|
|
|
|
if (!fTested)
|
|
{
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_READ ,&hKey))
|
|
{
|
|
DWORD cbData;
|
|
|
|
if (ERROR_SUCCESS == RegQueryValueEx(hKey, "ProductSuite", NULL, NULL, NULL, &cbData))
|
|
{
|
|
CHAR *mszBuffer, *szCurPtr;
|
|
|
|
if (NULL != (mszBuffer = (CHAR *)GlobalAllocPtr(GHND, cbData)))
|
|
{
|
|
RegQueryValueEx(hKey, "ProductSuite", NULL, NULL, (LPBYTE)mszBuffer, &cbData);
|
|
for(szCurPtr = mszBuffer; 0 != *szCurPtr; szCurPtr += lstrlen(szCurPtr)+1)
|
|
{
|
|
if(0 == lstrcmpi(szCurPtr, "Terminal Server"))
|
|
{
|
|
fHydra = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
GlobalFreePtr(mszBuffer);
|
|
}
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
fTested = TRUE;
|
|
}
|
|
|
|
return(fHydra);
|
|
}
|
|
|
|
#if 0
|
|
|
|
#define MEMALLOC(x) LocalAlloc(LMEM_FIXED, x)
|
|
#define MEMFREE(x) LocalFree(x)
|
|
|
|
//
|
|
BOOL SetRegKeyAccessRight(HKEY hKey)
|
|
{
|
|
PSECURITY_DESCRIPTOR psd;
|
|
PACL pacl;
|
|
DWORD cbacl;
|
|
|
|
PSID psid, psid2;
|
|
BOOL fResult = FALSE;
|
|
|
|
psid = MyCreateSid(SECURITY_INTERACTIVE_RID);
|
|
if (psid == NULL)
|
|
return NULL;
|
|
|
|
psid2 = MyCreateSid(SECURITY_LOCAL_SYSTEM_RID);
|
|
if (psid2 == NULL)
|
|
{
|
|
FreeSid (psid);
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// allocate and initialize an access control list (ACL) that will
|
|
// contain the SIDs we've just created.
|
|
//
|
|
cbacl = sizeof(ACL) +
|
|
(sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) * 2 +
|
|
GetLengthSid(psid);
|
|
|
|
pacl = (PACL)MEMALLOC(cbacl);
|
|
if (pacl == NULL)
|
|
{
|
|
FreeSid(psid);
|
|
FreeSid(psid2);
|
|
return FALSE;
|
|
}
|
|
|
|
fResult = InitializeAcl(pacl, cbacl, ACL_REVISION);
|
|
if (!fResult)
|
|
goto ExitError;
|
|
|
|
//
|
|
// adds an access-allowed ACE for interactive users to the ACL
|
|
//
|
|
fResult = AddAccessAllowedAce(pacl,
|
|
ACL_REVISION,
|
|
KEY_ALL_ACCESS,
|
|
psid);
|
|
|
|
if (!fResult)
|
|
goto ExitError;
|
|
|
|
//
|
|
// adds an access-allowed ACE for operating system to the ACL
|
|
//
|
|
fResult = AddAccessAllowedAce(pacl,
|
|
ACL_REVISION,
|
|
GENERIC_ALL,
|
|
psid2);
|
|
|
|
if (!fResult)
|
|
goto ExitError;
|
|
|
|
//
|
|
// Those SIDs have been copied into the ACL. We don't need'em any more.
|
|
//
|
|
FreeSid(psid);
|
|
FreeSid(psid2);
|
|
|
|
//
|
|
// Let's make sure that our ACL is valid.
|
|
//
|
|
if (!IsValidAcl(pacl))
|
|
{
|
|
//WARNOUT( TEXT("CreateSecurityAttributes:IsValidAcl returns fFalse!"));
|
|
MEMFREE(pacl);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// allocate and initialize a new security descriptor
|
|
//
|
|
psd = MEMALLOC(SECURITY_DESCRIPTOR_MIN_LENGTH );
|
|
if (psd == NULL)
|
|
{
|
|
//ERROROUT( TEXT("CreateSecurityAttributes:LocalAlloc for psd failed") );
|
|
MEMFREE(pacl);
|
|
return FALSE;
|
|
}
|
|
|
|
if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION))
|
|
goto Exit;
|
|
|
|
fResult = SetSecurityDescriptorDacl( psd,
|
|
TRUE,
|
|
pacl,
|
|
FALSE );
|
|
|
|
// The discretionary ACL is referenced by, not copied
|
|
// into, the security descriptor. We shouldn't free up ACL
|
|
// after the SetSecurityDescriptorDacl call.
|
|
|
|
if (!fResult)
|
|
goto Exit;
|
|
|
|
if (!IsValidSecurityDescriptor(psd))
|
|
goto Exit;
|
|
|
|
fResult = (RegSetKeySecurity(hKey, (SECURITY_INFORMATION)DACL_SECURITY_INFORMATION, psd) == ERROR_SUCCESS);
|
|
|
|
Exit:
|
|
MEMFREE(pacl);
|
|
FreeSid(psd);
|
|
|
|
return fResult;
|
|
|
|
ExitError:
|
|
FreeSid(psid);
|
|
FreeSid(psid2);
|
|
MEMFREE(pacl);
|
|
return FALSE;
|
|
}
|
|
|
|
// Create SID for all users
|
|
PSID MyCreateSid(DWORD dwSubAuthority)
|
|
{
|
|
PSID psid;
|
|
BOOL fResult;
|
|
SID_IDENTIFIER_AUTHORITY SidAuthority = SECURITY_NT_AUTHORITY;
|
|
|
|
//
|
|
// allocate and initialize an SID
|
|
//
|
|
fResult = AllocateAndInitializeSid(&SidAuthority,
|
|
1,
|
|
dwSubAuthority,
|
|
0,0,0,0,0,0,0,
|
|
&psid );
|
|
if (!fResult)
|
|
{
|
|
//ERROROUT( TEXT("MyCreateSid:AllocateAndInitializeSid failed") );
|
|
return NULL;
|
|
}
|
|
|
|
if (!IsValidSid(psid))
|
|
{
|
|
//WARNOUT(TEXT("MyCreateSid:AllocateAndInitializeSid returns bogus sid"));
|
|
FreeSid(psid);
|
|
return NULL;
|
|
}
|
|
|
|
return psid;
|
|
}
|
|
#endif
|