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