Leaked source code of windows server 2003
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.
 
 
 
 
 
 

922 lines
29 KiB

/****************************************************************************
WINMAIN.CPP : Per-user migration and reg install
History:
22-SEP-2000 CSLim Created
****************************************************************************/
#include "private.h"
#include <shlobj.h>
#include "hklhelp.h"
#include "msctf.h"
#include <initguid.h>
#include "common.h"
#define MEMALLOC(x) LocalAlloc(LMEM_FIXED, x)
#define MEMFREE(x) LocalFree(x)
// Current Major version. Whistler has IME 6.1
#define MAJORVER "6.1"
// IME 6.1 main module
#define SZMODULENAME_MAIN "imekr61.ime"
#define IME_REGISTRY_MIGRATION "IMEKRMIG6.1"
extern BOOL WINAPI IsNT();
// Private functions
static void MigrateUserData(HKEY hKeyCurrentUser);
static void WriteHKCUData(HKEY hKeyCurrentUser);
static BOOL IsNewerAppsIMEExist();
static VOID EnableTIPByDefault(GUID clsidTIP, GUID guidProfile, BOOL fEnable);
static VOID EnableTIP(GUID clsidTIP, GUID guidProfile, BOOL fEnable);
static VOID DisableTIP61();
static VOID DisableTIP60();
static PSID KYGetCurrentSID();
static BOOL GetTextualSid(PSID pSid, LPSTR TextualSid, LPDWORD dwBufferLen);
static void GetSIDString(LPSTR tszBuffer, SIZE_T cbBuffLen);
static POSVERSIONINFO GetVersionInfo();
static void CheckForDeleteRunReg();
static DWORD OpenUserKeyForWin9xUpgrade(LPSTR pszUserKeyA, HKEY *phKey);
static void RestoreMajorVersionRegistry();
static PSECURITY_DESCRIPTOR CreateSD();
static PSID MyCreateSid(DWORD dwSubAuthority);
/*---------------------------------------------------------------------------
WinMain
---------------------------------------------------------------------------*/
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
HKEY hKeyCurrentUser = NULL, hKey = NULL;
TCHAR szMigrateUserKey[MAX_PATH];
TCHAR szBuffer[500];
HKL hKL;
BOOL fMigrationAlreadyDone = FALSE;
BOOL fWin9xMig = FALSE;
if (lpCmdLine)
{
LPSTR sz_Arg1 = NULL;
LPSTR sz_Arg2 = NULL;
sz_Arg1 = strtok(lpCmdLine, " \t");
sz_Arg2 = strtok(NULL, " \t");
if (lstrcmpi(sz_Arg1, "Win9xMig") == 0)
{
OpenUserKeyForWin9xUpgrade(sz_Arg2, &hKeyCurrentUser);
if (hKeyCurrentUser != NULL)
fWin9xMig = TRUE;
}
}
if (hKeyCurrentUser == NULL)
hKeyCurrentUser = HKEY_CURRENT_USER;
StringCchCopy(szMigrateUserKey, ARRAYSIZE(szMigrateUserKey), g_szIMERootKey);
StringCchCat(szMigrateUserKey, ARRAYSIZE(szMigrateUserKey), "\\MigrateUser");
// Check Migrated flag
if (RegOpenKeyEx(hKeyCurrentUser, g_szIMERootKey, 0, KEY_ALL_ACCESS, &hKey)== ERROR_SUCCESS )
{
if (RegQueryValueEx(hKey, "Migrated", NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
fMigrationAlreadyDone = TRUE;
else
fMigrationAlreadyDone = FALSE;
RegCloseKey(hKey);
}
// if sid exists under HKLM\Software\Microsoft\IMEKR\6.1\MigrateUser migrate and delete sid from reg
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szMigrateUserKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
GetSIDString(szBuffer, sizeof(szBuffer)); // get the sid of the current user
if (RegQueryValueEx(hKey, szBuffer, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
HKEY hKeyRW;
// Get R/W access again.
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szMigrateUserKey, 0, KEY_ALL_ACCESS, &hKeyRW) == ERROR_SUCCESS)
{
// Delete current user's sid
RegDeleteValue(hKeyRW, szBuffer);
// Change MigrateUser List security settings
PSECURITY_DESCRIPTOR pSD = CreateSD();
if (pSD)
{
RegSetKeySecurity(hKeyRW, DACL_SECURITY_INFORMATION, pSD);
MEMFREE(pSD);
}
RegCloseKey(hKeyRW);
}
}
else
fMigrationAlreadyDone = TRUE;
RegCloseKey(hKey);
}
// If no more user list for migration, delete run reg.
if (!fWin9xMig)
CheckForDeleteRunReg();
// in, Lab06 2643 build Profilelist NULL when IMKRINST.EXE run.
//if (fMigrationAlreadyDone)
// return (0);
if (!IsNewerAppsIMEExist())
{
if (!fMigrationAlreadyDone || fWin9xMig)
{
// 1. Do migrate
MigrateUserData(hKeyCurrentUser);
// 2. Write any HKCU data
WriteHKCUData(hKeyCurrentUser);
// 3. Clean up HKCU preload reg. (Remove old IME)
hKL = GetHKLfromHKLM(SZMODULENAME_MAIN);
if (hKL && HKLHelp412ExistInPreload(hKeyCurrentUser))
{
AddPreload(hKeyCurrentUser, hKL);
// Enable TIP
EnableTIP(CLSID_KorIMX, GUID_Profile, fTrue);
}
// Set migrated reg
if (RegOpenKeyEx(hKeyCurrentUser, g_szIMERootKey, 0, KEY_ALL_ACCESS, &hKey)== ERROR_SUCCESS )
{
DWORD dwMigrated = 1;
RegSetValueEx(hKey, "Migrated", 0, REG_DWORD, (BYTE *)&dwMigrated, sizeof(DWORD));
RegCloseKey(hKey);
}
}
// !!! WORKAROUND CODE !!!
// Check if IME HKL exist in HKU\.Default, then enable the TIP by default.
// In US Whistler, IME HKL added to "HKU\.Default\KeyboarLayout\Preload" after IMKRINST.EXE run
// But IMKRINST disable KOR TIP if there is no Kor IME in the preload.
// So this code reenable the default setting. Only work when admin right user first logon.
if (RegOpenKeyEx(HKEY_USERS, TEXT(".DEFAULT"), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
if (HKLHelp412ExistInPreload(hKey))
EnableTIPByDefault(CLSID_KorIMX, GUID_Profile, fTrue);
RegCloseKey(hKey);
}
// !!! End of WORKAROUND CODE !!!
// If IME 6.0 TIP(Office 10 IME) exist in system, Disable it.
DisableTIP60();
}
else
{
// Remove IME 6.1 from Preload
hKL = GetHKLfromHKLM(SZMODULENAME_MAIN);
HKLHelpRemoveFromPreload(hKeyCurrentUser, hKL);
DisableTIP61();
}
if (hKeyCurrentUser != HKEY_CURRENT_USER)
RegCloseKey(hKeyCurrentUser);
return(0);
}
//////////////////////////////////////////////////////////////////////////////
// Private functions
//////////////////////////////////////////////////////////////////////////////
/*---------------------------------------------------------------------------
MigrateUserData
This function migrate BeolSik and K1 Hanja setting
Search IME98, Win95 IME, NT4 IME and AIME reg.
---------------------------------------------------------------------------*/
void MigrateUserData(HKEY hKeyCurrentUser)
{
const INT iMaxIMERegKeys = 5;
static LPSTR rgszOldIMERegKeys[iMaxIMERegKeys] =
{
// IME 2002(6.0)
"Software\\Microsoft\\IMEKR\\6.0",
// IME98
"Software\\Microsoft\\Windows\\CurrentVersion\\IME\\Korea\\IMEKR98U",
// Win95 IME
"Software\\Microsoft\\Windows\\CurrentVersion\\MSIME95",
// Kor NT4 IME
"Software\\Microsoft\\Windows\\CurrentVersion\\MSIME95K",
// Korean AIME
"Software\\Microsoft\\Windows\\CurrentVersion\\Wansung"
};
// Beolsik value
static CHAR szBeolsik[] = "InputMethod";
// K1 Hanja enable(IME98 only)
static CHAR szEnableK1Hanja[] = "KSC5657";
HKEY hKey;
DWORD dwCb, dwIMEKL, dwKSC5657;
// Set default values
dwIMEKL = dwKSC5657 = 0;
for (INT i=0; i<iMaxIMERegKeys; i++)
{
if (RegOpenKeyEx(hKeyCurrentUser, rgszOldIMERegKeys[i], 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
///////////////////////////////////////////////////////////////////
// Get Beolsik
dwCb = sizeof(dwIMEKL);
if (RegQueryValueEx(hKey, szBeolsik, NULL, NULL, (LPBYTE)&dwIMEKL, &dwCb) != ERROR_SUCCESS)
{
dwIMEKL = 0;
}
///////////////////////////////////////////////////////////////////
// Get K1 Hanja Setting
dwCb = sizeof(dwKSC5657);
if (RegQueryValueEx(hKey, szEnableK1Hanja, NULL, NULL, (LPBYTE)&dwKSC5657, &dwCb) != ERROR_SUCCESS)
{
dwKSC5657 = 0;
}
RegCloseKey(hKey);
// Break for loop
break;
}
}
// Set values to IME2002 reg
if (RegCreateKey(hKeyCurrentUser, g_szIMERootKey, &hKey) == ERROR_SUCCESS)
{
// 1. BeolSik
dwCb = sizeof(dwIMEKL);
if (dwIMEKL >= 100 && dwIMEKL <= 102)
dwIMEKL -= 100;
else
if (dwIMEKL > 2) // Only accept 0, 1, 2
dwIMEKL = 0;
RegSetValueEx(hKey, szBeolsik, 0, REG_DWORD, (LPBYTE)&dwIMEKL, dwCb);
// K1 Hanja flag
if (dwKSC5657 != 0 && dwKSC5657 != 1) // Only accept 0 or 1
dwKSC5657 = 0;
RegSetValueEx(hKey, szEnableK1Hanja, 0, REG_DWORD, (LPBYTE)&dwKSC5657, dwCb);
RegCloseKey(hKey);
}
}
/*---------------------------------------------------------------------------
WriteHKCUData
---------------------------------------------------------------------------*/
void WriteHKCUData(HKEY hKeyCurrentUser)
{
HKEY hKey;
// Set default Tip as for Cicero.
CoInitialize(NULL);
ITfInputProcessorProfiles *pProfile;
HRESULT hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfiles, (void **) &pProfile);
if (SUCCEEDED(hr))
{
pProfile->SetDefaultLanguageProfile(MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT),
CLSID_KorIMX, GUID_Profile);
pProfile->Release();
}
CoUninitialize();
// Reset Show Status
if (RegOpenKeyEx(hKeyCurrentUser, "Control Panel\\Input Method", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
LPSTR szStatus = "1";
RegSetValueEx(hKey, "Show Status", 0, REG_SZ, (BYTE *)szStatus, (sizeof(CHAR)*lstrlen(szStatus)));
RegCloseKey(hKey);
}
}
/*---------------------------------------------------------------------------
IsNewerAppsIMEExist
---------------------------------------------------------------------------*/
BOOL IsNewerAppsIMEExist()
{
HKEY hKey;
float flInstalledVersion, flVersion;
CHAR szVersion[MAX_PATH];
DWORD cbVersion = MAX_PATH;
BOOL fNewer = FALSE;
RestoreMajorVersionRegistry();
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_szVersionKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
if (RegQueryValueEx(hKey, "version", NULL, NULL, (BYTE *)szVersion, &cbVersion) == ERROR_SUCCESS)
{
flInstalledVersion = (float)atof(szVersion);
flVersion = (float)atof(MAJORVER);
if (flVersion < flInstalledVersion)
fNewer = TRUE;
}
RegCloseKey(hKey);
}
return fNewer;
}
/*---------------------------------------------------------------------------
DisableTIP60ByDefault
---------------------------------------------------------------------------*/
VOID EnableTIPByDefault(GUID clsidTIP, GUID guidProfile, BOOL fEnable)
{
// Set default Tip as for Cicero.
CoInitialize(NULL);
ITfInputProcessorProfiles *pProfile;
HRESULT hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfiles, (void **) &pProfile);
if (SUCCEEDED(hr))
{
pProfile->EnableLanguageProfileByDefault(clsidTIP,
MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT), guidProfile, fEnable);
pProfile->Release();
}
CoUninitialize();
}
/*---------------------------------------------------------------------------
EnableTip
---------------------------------------------------------------------------*/
VOID EnableTIP(GUID clsidTIP, GUID guidProfile, BOOL fEnable)
{
// Set default Tip as for Cicero.
CoInitialize(NULL);
ITfInputProcessorProfiles *pProfile;
HRESULT hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfiles, (void **) &pProfile);
if (SUCCEEDED(hr))
{
BOOL fCurEnabled = FALSE;
pProfile->IsEnabledLanguageProfile(clsidTIP,
MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT), guidProfile, &fCurEnabled);
if (fCurEnabled != fEnable)
pProfile->EnableLanguageProfile(clsidTIP,
MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT), guidProfile, fEnable);
pProfile->Release();
}
CoUninitialize();
}
/*---------------------------------------------------------------------------
DisableTip61
---------------------------------------------------------------------------*/
VOID DisableTIP61()
{
// Disable from HKLM
EnableTIPByDefault(CLSID_KorIMX, GUID_Profile, fFalse); // Actually mig exe was not registered by IMKRINST.EXE if newer apps IME exist.
// Dsiable from HKCU to make sure
EnableTIP(CLSID_KorIMX, GUID_Profile, fFalse);
}
/*---------------------------------------------------------------------------
DisableTip60
---------------------------------------------------------------------------*/
VOID DisableTIP60()
{
// KorIMX CLSID
// {766A2C14-B226-4fd6-B52A-867B3EBF38D2}
const static CLSID CLSID_KorTIP60 =
{
0x766A2C14,
0xB226,
0x4FD6,
{0xb5, 0x2a, 0x86, 0x7b, 0x3e, 0xbf, 0x38, 0xd2}
};
const static GUID g_guidProfile60 =
// {E47ABB1E-46AC-45f3-8A89-34F9D706DA83}
{ 0xe47abb1e,
0x46ac,
0x45f3,
{0x8a, 0x89, 0x34, 0xf9, 0xd7, 0x6, 0xda, 0x83}
};
// Disable from HKLM
EnableTIPByDefault(CLSID_KorTIP60, g_guidProfile60, fFalse); // Actually already done by IMKRINST.EXE
// Dsiable from HKCU to make sure
EnableTIP(CLSID_KorTIP60, g_guidProfile60, fFalse);
}
/*---------------------------------------------------------------------------
GetTextualSid
---------------------------------------------------------------------------*/
BOOL GetTextualSid(PSID pSid, LPSTR TextualSid, LPDWORD dwBufferLen)
{
PSID_IDENTIFIER_AUTHORITY psia;
DWORD dwSubAuthorities;
DWORD dwSidRev=SID_REVISION;
DWORD dwCounter;
DWORD dwSidSize;
if (!IsValidSid(pSid))
return FALSE;
// SidIdentifierAuthority ???
psia=GetSidIdentifierAuthority(pSid);
dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
// S-SID_REVISION- + identifierauthority- + subauthorities- + NULL
dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
if (*dwBufferLen < dwSidSize)
{
*dwBufferLen = dwSidSize;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
// S-SID_REVISION
dwSidSize=wsprintf(TextualSid, TEXT("S-%lu-"), dwSidRev );
// SidIdentifierAuthority
if ((psia->Value[0] != 0) || (psia->Value[1] != 0))
{
dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid),
TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
(USHORT)psia->Value[0],
(USHORT)psia->Value[1],
(USHORT)psia->Value[2],
(USHORT)psia->Value[3],
(USHORT)psia->Value[4],
(USHORT)psia->Value[5]);
}
else
{
dwSidSize+=wsprintf(TextualSid + lstrlen(TextualSid),
TEXT("%lu"),
(ULONG)(psia->Value[5] ) +
(ULONG)(psia->Value[4] << 8) +
(ULONG)(psia->Value[3] << 16) +
(ULONG)(psia->Value[2] << 24) );
}
// SidSubAuthorities
for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
{
dwSidSize += wsprintf(TextualSid + dwSidSize, TEXT("-%lu"),
*GetSidSubAuthority(pSid, dwCounter) );
}
return fTrue;
}
/*---------------------------------------------------------------------------
KYGetCurrentSID
---------------------------------------------------------------------------*/
PSID KYGetCurrentSID()
{
HANDLE hToken = NULL;
BOOL bSuccess;
#define MY_BUFSIZE 512 // highly unlikely to exceed 512 bytes
static UCHAR InfoBuffer[MY_BUFSIZE];
DWORD cbInfoBuffer = MY_BUFSIZE;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
return(NULL);
bSuccess = GetTokenInformation(
hToken,
TokenUser,
InfoBuffer,
cbInfoBuffer,
&cbInfoBuffer
);
if (!bSuccess)
{
if(GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
//
// alloc buffer and try GetTokenInformation() again
//
CloseHandle(hToken);
return(NULL);
}
else
{
//
// error getting token info
//
CloseHandle(hToken);
return(NULL);
}
}
CloseHandle(hToken);
return(((PTOKEN_USER)InfoBuffer)->User.Sid);
}
/*---------------------------------------------------------------------------
GetSIDString
---------------------------------------------------------------------------*/
void GetSIDString(LPSTR tszBuffer, SIZE_T cbBuffLen)
{
DWORD cbBuffer = (DWORD)cbBuffLen;
if (!GetTextualSid(KYGetCurrentSID(), tszBuffer, &cbBuffer))
tszBuffer[0] = 0;
}
/*---------------------------------------------------------------------------
GetVersionInfo
---------------------------------------------------------------------------*/
POSVERSIONINFO GetVersionInfo()
{
static BOOL fFirstCall = fTrue;
static OSVERSIONINFO os;
if (fFirstCall)
{
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&os))
fFirstCall = fFalse;
}
return &os;
}
/*---------------------------------------------------------------------------
IsNT
---------------------------------------------------------------------------*/
BOOL WINAPI IsNT()
{
BOOL fResult;
fResult = (GetVersionInfo()->dwPlatformId == VER_PLATFORM_WIN32_NT);
return fResult;
}
/*---------------------------------------------------------------------------
CheckForDeleteRunReg
---------------------------------------------------------------------------*/
void CheckForDeleteRunReg()
{
HKEY hKey, hRunKey;
TCHAR szValueName[MAX_PATH];
TCHAR szMigUserKey[MAX_PATH];
DWORD cbValueName = MAX_PATH;
BOOL fRemoveRunKey = FALSE;
StringCchCopy(szMigUserKey, ARRAYSIZE(szMigUserKey), g_szIMERootKey);
StringCchCat(szMigUserKey, ARRAYSIZE(szMigUserKey), TEXT("\\MigrateUser"));
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szMigUserKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
if (RegEnumValue(hKey, 0, szValueName, &cbValueName, NULL, NULL, NULL, NULL) == ERROR_NO_MORE_ITEMS)
fRemoveRunKey = TRUE;
RegCloseKey(hKey);
}
else
fRemoveRunKey = TRUE;
if (fRemoveRunKey &&
(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS, &hRunKey)) == ERROR_SUCCESS)
{
RegDeleteValue(hRunKey, IME_REGISTRY_MIGRATION);
RegCloseKey(hRunKey);
}
}
//
// On upgrades from Win9x we are passed a string value representing the
// key under which we'll find the user's Control Panel\Appearance subkey.
// The string is in the form "HKCU\$$$". We first translate the root key
// descriptor into a true root key then pass that root and the "$$$"
// part onto RegOpenKeyEx. This function takes that string and opens
// the associated hive key.
//
DWORD OpenUserKeyForWin9xUpgrade(LPSTR pszUserKeyA, HKEY *phKey)
{
DWORD dwResult = ERROR_INVALID_PARAMETER;
if (NULL != pszUserKeyA && NULL != phKey)
{
typedef struct {
char *pszRootA;
HKEY hKeyRoot;
} REGISTRY_ROOTS, *PREGISTRY_ROOTS;
static REGISTRY_ROOTS rgRoots[] = {
{ "HKLM", HKEY_LOCAL_MACHINE },
{ "HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE },
{ "HKCC", HKEY_CURRENT_CONFIG },
{ "HKEY_CURRENT_CONFIG", HKEY_CURRENT_CONFIG },
{ "HKU", HKEY_USERS },
{ "HKEY_USERS", HKEY_USERS },
{ "HKCU", HKEY_CURRENT_USER },
{ "HKEY_CURRENT_USER", HKEY_CURRENT_USER },
{ "HKCR", HKEY_CLASSES_ROOT },
{ "HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT }
};
char szUserKeyA[MAX_PATH]; // For a local copy.
LPSTR pszSubKeyA = szUserKeyA;
//
// Make a local copy that we can modify.
//
lstrcpynA(szUserKeyA, pszUserKeyA, ARRAYSIZE(szUserKeyA));
*phKey = NULL;
//
// Find the backslash.
//
while(*pszSubKeyA && '\\' != *pszSubKeyA)
pszSubKeyA++;
if ('\\' == *pszSubKeyA)
{
HKEY hkeyRoot = NULL;
int i;
//
// Replace backslash with nul to separate the root key and
// sub key strings in our local copy of the original argument
// string.
//
*pszSubKeyA++ = '\0';
//
// Now find the true root key in rgRoots[].
//
for (i = 0; i < ARRAYSIZE(rgRoots); i++)
{
if (0 == lstrcmpiA(rgRoots[i].pszRootA, szUserKeyA))
{
hkeyRoot = rgRoots[i].hKeyRoot;
break;
}
}
if (NULL != hkeyRoot)
{
//
// Open the key.
//
dwResult = RegOpenKeyExA(hkeyRoot,
pszSubKeyA,
0,
KEY_ALL_ACCESS,
phKey);
}
}
}
return dwResult;
}
/*---------------------------------------------------------------------------
RestoreMajorVersionRegistry
Restore IME major version reg value.
It could be overwritten during Win9x to NT upgrade.
---------------------------------------------------------------------------*/
void RestoreMajorVersionRegistry()
{
HKEY hKey;
///////////////////////////////////////////////////////////////////////////
// Restore IME major version reg value.
// It could be overwritten during Win9x to NT upgrading.
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_szVersionKey, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
CHAR szVersion[MAX_PATH];
DWORD cbVersion = MAX_PATH;
CHAR szMaxVersion[MAX_PATH];
FILETIME time;
float flVersion, flMaxVersion;
StringCchCopy(szMaxVersion, ARRAYSIZE(szMaxVersion), "0");
for (int i=0; cbVersion = MAX_PATH, RegEnumKeyEx(hKey, i, szVersion, &cbVersion, NULL, NULL, NULL, &time) != ERROR_NO_MORE_ITEMS; i++)
{
if (lstrcmp(szVersion, szMaxVersion) > 0)
StringCchCopy(szMaxVersion, ARRAYSIZE(szMaxVersion), szVersion);
}
StringCchCopy(szVersion, ARRAYSIZE(szVersion), "0");
RegQueryValueEx(hKey, g_szVersion, NULL, NULL, (BYTE *)szVersion, &cbVersion);
flVersion = (float)atof(szVersion);
flMaxVersion = (float)atof(szMaxVersion);
if (flVersion < flMaxVersion)
RegSetValueEx(hKey, g_szVersion, 0, REG_SZ, (BYTE *)szMaxVersion, (sizeof(CHAR)*lstrlen(szMaxVersion)));
RegCloseKey(hKey);
}
///////////////////////////////////////////////////////////////////////////
}
/*---------------------------------------------------------------------------
CreateSecurityAttributes
---------------------------------------------------------------------------*/
PSECURITY_DESCRIPTOR CreateSD()
{
PSECURITY_DESCRIPTOR psd;
PACL pacl;
ULONG AclSize;
PSID psid1, psid2, psid3, psid4;
BOOL fResult;
psid1 = MyCreateSid(SECURITY_INTERACTIVE_RID);
if (psid1 == NULL)
return NULL;
psid2 = MyCreateSid(SECURITY_LOCAL_SYSTEM_RID);
if (psid2 == NULL)
goto Fail4;
psid3 = MyCreateSid(SECURITY_SERVICE_RID);
if (psid3 == NULL)
goto Fail3;
psid4 = MyCreateSid(SECURITY_NETWORK_RID);
if (psid4 == NULL)
goto Fail2;
//
// allocate and initialize an access control list (ACL) that will
// contain the SIDs we've just created.
//
AclSize = sizeof(ACL) +
(4 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG))) +
GetLengthSid(psid1) +
GetLengthSid(psid2) +
GetLengthSid(psid3) +
GetLengthSid(psid4);
//
// allocate and initialize a new security descriptor plus ACL
//
psd = MEMALLOC(SECURITY_DESCRIPTOR_MIN_LENGTH + AclSize);
if (psd == NULL)
{
return NULL;
}
pacl = (PACL)((LPBYTE)psd + SECURITY_DESCRIPTOR_MIN_LENGTH);
fResult = InitializeAcl(pacl, AclSize, ACL_REVISION);
if (!fResult)
{
goto Fail;
}
//
// adds an access-allowed ACE for interactive users to the ACL
//
fResult = AddAccessAllowedAce(pacl,
ACL_REVISION,
GENERIC_ALL,
psid1);
if (!fResult)
{
goto Fail;
}
//
// adds an access-allowed ACE for operating system to the ACL
//
fResult = AddAccessAllowedAce(pacl,
ACL_REVISION,
GENERIC_ALL,
psid2);
if (!fResult)
{
goto Fail;
}
//
// adds an access-allowed ACE for operating system to the ACL
//
fResult = AddAccessAllowedAce(pacl,
ACL_REVISION,
GENERIC_ALL,
psid3);
if (!fResult)
{
goto Fail;
}
//
// adds an access-allowed ACE for operating system to the ACL
//
fResult = AddAccessAllowedAce(pacl,
ACL_REVISION,
GENERIC_ALL,
psid4);
if (!fResult)
{
goto Fail;
}
//
// Let's make sure that our ACL is valid.
//
if (!IsValidAcl(pacl))
{
goto Fail;
}
if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION))
{
goto Fail;
}
fResult = SetSecurityDescriptorDacl(psd, fTrue, pacl, fFalse );
// 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 Fail;
}
if (!IsValidSecurityDescriptor(psd))
{
goto Fail;
}
//
// Those SIDs have been copied into the ACL. We don't need'em any more.
//
FreeSid(psid1);
FreeSid(psid2);
FreeSid(psid3);
FreeSid(psid4);
return psd;
Fail:
MEMFREE(psd);
FreeSid(psid4);
Fail2:
FreeSid(psid3);
Fail3:
FreeSid(psid2);
Fail4:
FreeSid(psid1);
return NULL;
}
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)
{
return NULL;
}
if (!IsValidSid(psid))
{
FreeSid(psid);
return NULL;
}
return psid;
}