mirror of https://github.com/tongzx/nt5src
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.
856 lines
21 KiB
856 lines
21 KiB
//*************************************************************
|
|
// File name: profile.c
|
|
//
|
|
// Description: Fixes hard coded paths in the registry for
|
|
// special folder locations. Also fixes security
|
|
// on a few registry keys.
|
|
//
|
|
// Microsoft Confidential
|
|
// Copyright (c) Microsoft Corporation 1996
|
|
// All rights reserved
|
|
//
|
|
//*************************************************************
|
|
|
|
#include <windows.h>
|
|
#include <shlobj.h>
|
|
#include <shlwapi.h>
|
|
#include <xpsp1res.h>
|
|
#include <userenv.h>
|
|
#include <userenvp.h>
|
|
#include <tchar.h>
|
|
#include "shmgdefs.h"
|
|
|
|
|
|
//*************************************************************
|
|
//
|
|
// ApplySecurityToRegistryTree()
|
|
//
|
|
// Purpose: Applies the passed security descriptor to the passed
|
|
// key and all its descendants. Only the parts of
|
|
// the descriptor inddicated in the security
|
|
// info value are actually applied to each registry key.
|
|
//
|
|
// Parameters: RootKey - Registry key
|
|
// pSD - Security Descriptor
|
|
//
|
|
// Return: ERROR_SUCCESS if successful
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 7/19/95 ericflo Created
|
|
// 6/16/96 bobday Stolen directly from USERENV
|
|
//
|
|
//*************************************************************
|
|
|
|
DWORD ApplySecurityToRegistryTree(HKEY RootKey, PSECURITY_DESCRIPTOR pSD)
|
|
|
|
{
|
|
DWORD Error;
|
|
DWORD SubKeyIndex;
|
|
LPTSTR SubKeyName;
|
|
HKEY SubKey;
|
|
DWORD cchSubKeySize = MAX_PATH + 1;
|
|
|
|
|
|
|
|
//
|
|
// First apply security
|
|
//
|
|
|
|
Error = RegSetKeySecurity(RootKey, DACL_SECURITY_INFORMATION, pSD);
|
|
|
|
if (Error != ERROR_SUCCESS) {
|
|
return Error;
|
|
}
|
|
|
|
|
|
//
|
|
// Open each sub-key and apply security to its sub-tree
|
|
//
|
|
|
|
SubKeyIndex = 0;
|
|
|
|
SubKeyName = GlobalAlloc (GPTR, cchSubKeySize * sizeof(TCHAR));
|
|
|
|
if (!SubKeyName) {
|
|
return GetLastError();
|
|
}
|
|
|
|
while (TRUE) {
|
|
|
|
//
|
|
// Get the next sub-key name
|
|
//
|
|
|
|
Error = RegEnumKey(RootKey, SubKeyIndex, SubKeyName, cchSubKeySize);
|
|
|
|
|
|
if (Error != ERROR_SUCCESS) {
|
|
|
|
if (Error == ERROR_NO_MORE_ITEMS) {
|
|
|
|
//
|
|
// Successful end of enumeration
|
|
//
|
|
|
|
Error = ERROR_SUCCESS;
|
|
|
|
} else {
|
|
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// Open the sub-key
|
|
//
|
|
|
|
Error = RegOpenKeyEx(RootKey,
|
|
SubKeyName,
|
|
0,
|
|
WRITE_DAC | KEY_ENUMERATE_SUB_KEYS | READ_CONTROL,
|
|
&SubKey);
|
|
|
|
if (Error != ERROR_SUCCESS) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Apply security to the sub-tree
|
|
//
|
|
|
|
Error = ApplySecurityToRegistryTree(SubKey, pSD);
|
|
|
|
|
|
//
|
|
// We're finished with the sub-key
|
|
//
|
|
|
|
RegCloseKey(SubKey);
|
|
|
|
//
|
|
// See if we set the security on the sub-tree successfully.
|
|
//
|
|
|
|
if (Error != ERROR_SUCCESS) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Go enumerate the next sub-key
|
|
//
|
|
|
|
SubKeyIndex ++;
|
|
}
|
|
|
|
|
|
GlobalFree (SubKeyName);
|
|
|
|
return Error;
|
|
|
|
}
|
|
|
|
//*************************************************************
|
|
//
|
|
// MakeKeyOrTreeSecure()
|
|
//
|
|
// Purpose: Sets the attributes on the registry key and possibly sub-keys
|
|
// such that Administrators and the OS can delete it and Everyone
|
|
// else has read permission only (OR general read/write access)
|
|
//
|
|
// Parameters: RootKey - Key to set security on
|
|
// fWrite - Allow write (or just read)
|
|
//
|
|
// Return: (BOOL) TRUE if successful
|
|
// FALSE if an error occurs
|
|
//
|
|
// Comments:
|
|
//
|
|
// History: Date Author Comment
|
|
// 11/6/95 ericflo Created
|
|
// 06/16/96 bobday Ported from MakeFileSecure in USERENV
|
|
//
|
|
//*************************************************************
|
|
|
|
BOOL MakeKeyOrTreeSecure (HKEY RootKey, BOOL fWrite)
|
|
{
|
|
SECURITY_DESCRIPTOR sd;
|
|
SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
|
|
SID_IDENTIFIER_AUTHORITY authWorld = SECURITY_WORLD_SID_AUTHORITY;
|
|
PACL pAcl = NULL;
|
|
PSID psidSystem = NULL, psidAdmin = NULL, psidEveryone = NULL;
|
|
DWORD cbAcl, aceIndex;
|
|
ACE_HEADER * lpAceHeader;
|
|
BOOL bRetVal = FALSE;
|
|
DWORD Error;
|
|
DWORD dwAccess;
|
|
|
|
|
|
|
|
if (fWrite) {
|
|
dwAccess = KEY_ALL_ACCESS;
|
|
} else {
|
|
dwAccess = KEY_READ;
|
|
}
|
|
|
|
//
|
|
// Get the system sid
|
|
//
|
|
|
|
if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID,
|
|
0, 0, 0, 0, 0, 0, 0, &psidSystem)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Get the Admin sid
|
|
//
|
|
|
|
if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS, 0, 0,
|
|
0, 0, 0, 0, &psidAdmin)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Get the World sid
|
|
//
|
|
|
|
if (!AllocateAndInitializeSid(&authWorld, 1, SECURITY_WORLD_RID,
|
|
0, 0, 0, 0, 0, 0, 0, &psidEveryone)) {
|
|
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Allocate space for the ACL
|
|
//
|
|
|
|
cbAcl = (3 * GetLengthSid (psidSystem)) +
|
|
(3 * GetLengthSid (psidAdmin)) + sizeof(ACL) +
|
|
(6 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)));
|
|
|
|
|
|
pAcl = (PACL) GlobalAlloc(GMEM_FIXED, cbAcl);
|
|
if (!pAcl) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
if (!InitializeAcl(pAcl, cbAcl, ACL_REVISION)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Add Aces. Non-inheritable ACEs first
|
|
//
|
|
|
|
aceIndex = 0;
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, KEY_ALL_ACCESS, psidSystem)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
aceIndex++;
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, KEY_ALL_ACCESS, psidAdmin)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
aceIndex++;
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, dwAccess, psidEveryone)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Now the inheritable ACEs
|
|
//
|
|
if (fWrite) {
|
|
dwAccess = GENERIC_ALL;
|
|
} else {
|
|
dwAccess = GENERIC_READ;
|
|
}
|
|
|
|
|
|
aceIndex++;
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidSystem)) {
|
|
goto Exit;
|
|
}
|
|
|
|
if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
|
|
goto Exit;
|
|
}
|
|
|
|
lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
|
|
|
|
|
|
aceIndex++;
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidAdmin)) {
|
|
goto Exit;
|
|
}
|
|
|
|
if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
|
|
goto Exit;
|
|
}
|
|
|
|
lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
|
|
|
|
aceIndex++;
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, dwAccess, psidEveryone)) {
|
|
goto Exit;
|
|
}
|
|
|
|
if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
|
|
goto Exit;
|
|
}
|
|
|
|
lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
|
|
|
|
|
|
//
|
|
// Put together the security descriptor
|
|
//
|
|
|
|
if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
if (!SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Set the security
|
|
//
|
|
Error = ApplySecurityToRegistryTree(RootKey, &sd);
|
|
|
|
if (Error == ERROR_SUCCESS) {
|
|
bRetVal = TRUE;
|
|
}
|
|
|
|
|
|
Exit:
|
|
|
|
if (psidSystem) {
|
|
FreeSid(psidSystem);
|
|
}
|
|
|
|
if (psidAdmin) {
|
|
FreeSid(psidAdmin);
|
|
}
|
|
|
|
|
|
if (psidEveryone) {
|
|
FreeSid(psidEveryone);
|
|
}
|
|
|
|
|
|
if (pAcl) {
|
|
GlobalFree (pAcl);
|
|
}
|
|
|
|
return bRetVal;
|
|
}
|
|
|
|
void FixWindowsProfileSecurity( void )
|
|
{
|
|
HKEY hkeyWindows;
|
|
HKEY hkeyShellExt;
|
|
DWORD Error;
|
|
|
|
Error = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
TEXT("Software\\Microsoft\\Windows"),
|
|
0,
|
|
WRITE_DAC | KEY_ENUMERATE_SUB_KEYS | READ_CONTROL,
|
|
&hkeyWindows);
|
|
|
|
if (Error == ERROR_SUCCESS)
|
|
{
|
|
MakeKeyOrTreeSecure(hkeyWindows, TRUE);
|
|
RegCloseKey(hkeyWindows);
|
|
}
|
|
|
|
Error = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions"),
|
|
0,
|
|
WRITE_DAC | KEY_ENUMERATE_SUB_KEYS | READ_CONTROL,
|
|
&hkeyShellExt);
|
|
if (Error == ERROR_SUCCESS)
|
|
{
|
|
MakeKeyOrTreeSecure(hkeyShellExt, FALSE);
|
|
RegCloseKey(hkeyShellExt);
|
|
}
|
|
}
|
|
|
|
void FixUserProfileSecurity( void )
|
|
{
|
|
HKEY hkeyPolicies;
|
|
DWORD Error;
|
|
|
|
Error = RegOpenKeyEx( HKEY_CURRENT_USER,
|
|
TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies"),
|
|
0,
|
|
WRITE_DAC | KEY_ENUMERATE_SUB_KEYS | READ_CONTROL,
|
|
&hkeyPolicies);
|
|
|
|
if (Error == ERROR_SUCCESS)
|
|
{
|
|
MakeKeyOrTreeSecure(hkeyPolicies, FALSE);
|
|
RegCloseKey(hkeyPolicies);
|
|
}
|
|
}
|
|
|
|
void FixPoliciesSecurity( void )
|
|
{
|
|
HKEY hkeyPolicies;
|
|
DWORD Error, dwDisp;
|
|
|
|
Error = RegCreateKeyEx( HKEY_CURRENT_USER,
|
|
TEXT("Software\\Policies"),
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
WRITE_DAC | KEY_ENUMERATE_SUB_KEYS | READ_CONTROL,
|
|
NULL,
|
|
&hkeyPolicies,
|
|
&dwDisp);
|
|
|
|
if (Error == ERROR_SUCCESS)
|
|
{
|
|
MakeKeyOrTreeSecure(hkeyPolicies, FALSE);
|
|
RegCloseKey(hkeyPolicies);
|
|
}
|
|
}
|
|
|
|
void SetSystemBitOnCAPIDir(void)
|
|
{
|
|
HRESULT hr;
|
|
TCHAR szPath[MAX_PATH];
|
|
TCHAR szAppData[MAX_PATH];
|
|
DWORD FileAttributes;
|
|
|
|
|
|
if (S_OK == SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, szAppData)){
|
|
|
|
//
|
|
// It is better to use tcscpy and tcscat. This is just a temp fix and it is build with
|
|
// Unicode anyway. Not worth to include extra header file.
|
|
// We do not check error case here. This is just a best effort. If we got error, so what?
|
|
// MAX_PATH should be enough for these DIRs. Not worth to take care of \\?\ format.
|
|
//
|
|
|
|
lstrcpyn(szPath, szAppData, ARRAYSIZE(szPath));
|
|
StrCatBuff(szPath, TEXT("\\Microsoft\\Protect"), ARRAYSIZE(szPath));
|
|
FileAttributes = GetFileAttributes(szPath);
|
|
if ((FileAttributes != -1) && ((FileAttributes & FILE_ATTRIBUTE_SYSTEM) == 0)) {
|
|
FileAttributes |= FILE_ATTRIBUTE_SYSTEM;
|
|
SetFileAttributes(szPath, FileAttributes);
|
|
}
|
|
|
|
lstrcpyn(szPath, szAppData, ARRAYSIZE(szPath));
|
|
StrCatBuff(szPath, TEXT("\\Microsoft\\Crypto"), ARRAYSIZE(szPath));
|
|
FileAttributes = GetFileAttributes(szPath);
|
|
if ((FileAttributes != -1) && ((FileAttributes & FILE_ATTRIBUTE_SYSTEM) == 0)) {
|
|
FileAttributes |= FILE_ATTRIBUTE_SYSTEM;
|
|
SetFileAttributes(szPath, FileAttributes);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void SetScreensaverOnFriendlyUI()
|
|
{
|
|
if (IsOS(OS_FRIENDLYLOGONUI) &&
|
|
IsOS(OS_FASTUSERSWITCHING))
|
|
{
|
|
HKEY hkey;
|
|
|
|
if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), 0, KEY_SET_VALUE, &hkey) == ERROR_SUCCESS)
|
|
{
|
|
TCHAR szTemp[MAX_PATH];
|
|
|
|
RegSetValueEx(hkey, TEXT("ScreenSaveActive"), 0, REG_SZ, (BYTE*)TEXT("1"), sizeof(TEXT("1")));
|
|
|
|
if (RegQueryValueEx(hkey, TEXT("SCRNSAVE.EXE"), NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
|
|
{
|
|
// if the user dosen't already have a screensaver set, then choose one for them!
|
|
if (ExpandEnvironmentStrings(TEXT("%SystemRoot%\\System32\\logon.scr"), szTemp, ARRAYSIZE(szTemp)))
|
|
{
|
|
RegSetValueEx(hkey, TEXT("SCRNSAVE.EXE"), 0, REG_SZ, (BYTE*)szTemp, (lstrlen(szTemp) + 1) * sizeof(TCHAR));
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#define OTHERSIDS_EVERYONE 1
|
|
#define OTHERSIDS_POWERUSERS 2
|
|
|
|
BOOL MakeFileSecure (LPTSTR lpFile, DWORD dwOtherSids)
|
|
{
|
|
SECURITY_DESCRIPTOR sd;
|
|
SECURITY_ATTRIBUTES sa;
|
|
SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
|
|
SID_IDENTIFIER_AUTHORITY authWORLD = SECURITY_WORLD_SID_AUTHORITY;
|
|
PACL pAcl = NULL;
|
|
PSID psidSystem = NULL, psidAdmin = NULL, psidUsers = NULL, psidPowerUsers = NULL;
|
|
PSID psidEveryOne = NULL;
|
|
DWORD cbAcl, aceIndex;
|
|
ACE_HEADER * lpAceHeader;
|
|
BOOL bRetVal = FALSE;
|
|
BOOL bAddPowerUsersAce=TRUE;
|
|
BOOL bAddEveryOneAce=FALSE;
|
|
DWORD dwAccMask;
|
|
|
|
|
|
//
|
|
// Get the system sid
|
|
//
|
|
|
|
if (!AllocateAndInitializeSid(&authNT, 1, SECURITY_LOCAL_SYSTEM_RID,
|
|
0, 0, 0, 0, 0, 0, 0, &psidSystem)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Get the Admin sid
|
|
//
|
|
|
|
if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS, 0, 0,
|
|
0, 0, 0, 0, &psidAdmin)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Get the users sid
|
|
//
|
|
|
|
if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_USERS,
|
|
0, 0, 0, 0, 0, 0, &psidUsers)) {
|
|
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Allocate space for the ACL
|
|
//
|
|
|
|
cbAcl = (2 * GetLengthSid (psidSystem)) +
|
|
(2 * GetLengthSid (psidAdmin)) +
|
|
(2 * GetLengthSid (psidUsers)) +
|
|
sizeof(ACL) +
|
|
(6 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)));
|
|
|
|
//
|
|
// Get the power users sid, if required.
|
|
// Don't fail if you don't get because it might not be available on DCs??
|
|
//
|
|
|
|
bAddPowerUsersAce = TRUE;
|
|
if (!AllocateAndInitializeSid(&authNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0, 0, &psidPowerUsers)) {
|
|
|
|
bAddPowerUsersAce = FALSE;
|
|
}
|
|
|
|
if (bAddPowerUsersAce)
|
|
cbAcl += (2 * GetLengthSid (psidPowerUsers)) + (2 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)));
|
|
|
|
//
|
|
// Get the EveryOne sid, if required.
|
|
//
|
|
|
|
if (dwOtherSids & OTHERSIDS_EVERYONE) {
|
|
bAddEveryOneAce = TRUE;
|
|
if (!AllocateAndInitializeSid(&authWORLD, 1, SECURITY_WORLD_RID,
|
|
0, 0, 0, 0, 0, 0, 0, &psidEveryOne)) {
|
|
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
if (bAddEveryOneAce)
|
|
cbAcl += (2 * GetLengthSid (psidEveryOne)) + (2 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)));
|
|
|
|
|
|
pAcl = (PACL) GlobalAlloc(GMEM_FIXED, cbAcl);
|
|
if (!pAcl) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
if (!InitializeAcl(pAcl, cbAcl, ACL_REVISION)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Add Aces. Non-inheritable ACEs first
|
|
//
|
|
|
|
aceIndex = 0;
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, psidSystem)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
aceIndex++;
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, psidAdmin)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
aceIndex++;
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, /*GENERIC_READ | GENERIC_EXECUTE,*/ psidUsers)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
if (bAddPowerUsersAce) {
|
|
|
|
//
|
|
// By default give read permissions, otherwise give modify permissions
|
|
//
|
|
|
|
dwAccMask = (dwOtherSids & OTHERSIDS_POWERUSERS) ? (FILE_ALL_ACCESS ^ (WRITE_DAC | WRITE_OWNER)):
|
|
(GENERIC_READ | GENERIC_EXECUTE);
|
|
|
|
aceIndex++;
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, /*dwAccMask,*/ psidPowerUsers)) {
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
if (bAddEveryOneAce) {
|
|
aceIndex++;
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, /*GENERIC_READ | GENERIC_EXECUTE,*/ psidEveryOne)) {
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now the inheritable ACEs
|
|
//
|
|
|
|
aceIndex++;
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidSystem)) {
|
|
goto Exit;
|
|
}
|
|
|
|
if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
|
|
goto Exit;
|
|
}
|
|
|
|
lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
|
|
|
|
|
|
aceIndex++;
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, psidAdmin)) {
|
|
goto Exit;
|
|
}
|
|
|
|
if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
|
|
goto Exit;
|
|
}
|
|
|
|
lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
|
|
|
|
|
|
aceIndex++;
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, /*GENERIC_READ | GENERIC_EXECUTE,*/ psidUsers)) {
|
|
goto Exit;
|
|
}
|
|
|
|
if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
|
|
goto Exit;
|
|
}
|
|
|
|
lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
|
|
|
|
|
|
if (bAddPowerUsersAce) {
|
|
aceIndex++;
|
|
dwAccMask = (dwOtherSids & OTHERSIDS_POWERUSERS) ? (FILE_ALL_ACCESS ^ (WRITE_DAC | WRITE_OWNER)):
|
|
(GENERIC_READ | GENERIC_EXECUTE);
|
|
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, /*dwAccMask,*/ psidPowerUsers)) {
|
|
goto Exit;
|
|
}
|
|
|
|
if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
|
|
goto Exit;
|
|
}
|
|
|
|
lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
|
|
}
|
|
|
|
if (bAddEveryOneAce) {
|
|
aceIndex++;
|
|
|
|
if (!AddAccessAllowedAce(pAcl, ACL_REVISION, FILE_ALL_ACCESS, /*GENERIC_READ | GENERIC_EXECUTE,*/ psidEveryOne)) {
|
|
goto Exit;
|
|
}
|
|
|
|
if (!GetAce(pAcl, aceIndex, &lpAceHeader)) {
|
|
goto Exit;
|
|
}
|
|
|
|
lpAceHeader->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
|
|
}
|
|
|
|
//
|
|
// Put together the security descriptor
|
|
//
|
|
|
|
if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
if (!SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE)) {
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Set the security
|
|
//
|
|
|
|
if (SetFileSecurity (lpFile, DACL_SECURITY_INFORMATION, &sd)) {
|
|
bRetVal = TRUE;
|
|
} else {
|
|
}
|
|
|
|
|
|
|
|
Exit:
|
|
|
|
if (psidSystem) {
|
|
FreeSid(psidSystem);
|
|
}
|
|
|
|
if (psidAdmin) {
|
|
FreeSid(psidAdmin);
|
|
}
|
|
|
|
|
|
if (psidUsers) {
|
|
FreeSid(psidUsers);
|
|
}
|
|
|
|
if ((bAddPowerUsersAce) && (psidPowerUsers)) {
|
|
FreeSid(psidPowerUsers);
|
|
}
|
|
|
|
if ((bAddEveryOneAce) && (psidEveryOne)) {
|
|
FreeSid(psidEveryOne);
|
|
}
|
|
|
|
if (pAcl) {
|
|
GlobalFree (pAcl);
|
|
}
|
|
|
|
return bRetVal;
|
|
}
|
|
|
|
|
|
#ifdef SHMG_DBG
|
|
|
|
void SHMGLogErrMsg(char *szErrMsg, DWORD dwError)
|
|
{
|
|
DWORD dwBytesWritten = 0;
|
|
char szMsg[256];
|
|
static HANDLE hLogFile = 0;
|
|
|
|
if (!hLogFile) {
|
|
hLogFile = CreateFile(_T("shmgrate.log"), GENERIC_WRITE,
|
|
FILE_SHARE_WRITE, 0,
|
|
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
|
|
}
|
|
|
|
sprintf(szMsg, "%s : (%X)\r\n", szErrMsg, dwError);
|
|
WriteFile(hLogFile, szMsg, strlen(szMsg), &dwBytesWritten, 0);
|
|
}
|
|
|
|
#endif
|
|
|
|
void
|
|
FixHtmlHelp(
|
|
void
|
|
)
|
|
{
|
|
TCHAR AppDataPath[MAX_PATH*2];
|
|
TCHAR HtmlHelpPath[MAX_PATH];
|
|
|
|
SHMGLogErrMsg("FixHtmlHelp Called",0);
|
|
|
|
if (SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, AppDataPath) == S_OK &&
|
|
LoadString( GetModuleHandle(NULL), IDS_HTML_HELP_DIR, HtmlHelpPath, sizeof(HtmlHelpPath)/sizeof(WCHAR) ) > 0)
|
|
{
|
|
_tcscat( AppDataPath, HtmlHelpPath );
|
|
|
|
if (CreateDirectory( AppDataPath, NULL )) {
|
|
if (!MakeFileSecure(AppDataPath,OTHERSIDS_EVERYONE|OTHERSIDS_POWERUSERS))
|
|
SHMGLogErrMsg("Could not apply security attributes", 0);
|
|
}
|
|
else
|
|
SHMGLogErrMsg("Could not create the directory", GetLastError());
|
|
}
|
|
else
|
|
SHMGLogErrMsg("Could not get APPDATA path", GetLastError());
|
|
}
|
|
|
|
// Add the SP1 "Configure Programs" shortcut to the common start menu
|
|
// On a clean install, this is handled by syssetup.inf, but on a
|
|
// RTM->SP1 upgrade, we need to do it by hand.
|
|
//
|
|
|
|
void AddConfigurePrograms()
|
|
{
|
|
if (!IsOS(OS_ANYSERVER))
|
|
{
|
|
TCHAR szPath[MAX_PATH];
|
|
|
|
if (GetSystemDirectory(szPath, ARRAYSIZE(szPath)) &&
|
|
PathAppend(szPath, TEXT("XPSP1RES.DLL")))
|
|
{
|
|
HINSTANCE hinstSp1 = LoadLibraryEx(szPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
|
|
if (hinstSp1)
|
|
{
|
|
TCHAR szTitle[MAX_PATH];
|
|
LoadString(hinstSp1, IDS_APPWIZ_CONFIGUREPROGRAMS, szTitle, ARRAYSIZE(szTitle));
|
|
CreateLinkFile(CSIDL_COMMON_STARTMENU, NULL, szTitle,
|
|
TEXT("control.exe appwiz.cpl,,3"),
|
|
TEXT("moricons.dll"), -114,
|
|
NULL, 0, SW_SHOWNORMAL, TEXT("@xpsp1res.dll,-10078"));
|
|
if (S_OK == SHGetFolderPath(NULL, CSIDL_COMMON_STARTMENU, NULL, SHGFP_TYPE_CURRENT, szPath) &&
|
|
PathAppend(szPath, szTitle) &&
|
|
PathAddExtension(szPath, TEXT(".lnk")))
|
|
{
|
|
SHSetLocalizedName(szPath, L"xpsp1res.dll", IDS_APPWIZ_CONFIGUREPROGRAMS);
|
|
}
|
|
}
|
|
FreeLibrary(hinstSp1);
|
|
}
|
|
}
|
|
}
|