newAceIndex = 0;
if (fDaclPresent && AclInfo.AceCount) {
for (CurrentAceIndex = 0;
CurrentAceIndex < AclInfo.AceCount;
CurrentAceIndex++) {
//
// STEP 10: Get an ACE.
//
if (!GetAce(pACL, CurrentAceIndex, &pTempAce)) {
_tprintf(TEXT("GetAce() failed. Error %d\n"),
GetLastError());
__leave;
}
//
// STEP 11: Check if it is a non-inherited ACE.
// If it is an inherited ACE, break from the loop so
// that the new access allowed non-inherited ACE can
// be added in the correct position, immediately after
// all non-inherited ACEs.
//
if (((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags
& INHERITED_ACE)
break;
//
// STEP 12: Skip adding the ACE, if the SID matches
// with the account specified, as we are going to
// add an access allowed ACE with a different access
// mask.
//
if (EqualSid(pUserSID,
&(((ACCESS_ALLOWED_ACE *)pTempAce)->SidStart)))
continue;
//
// STEP 13: Add the ACE to the new ACL.
//
if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,
((PACE_HEADER) pTempAce)->AceSize)) {
_tprintf(TEXT("AddAce() failed. Error %d\n"),
GetLastError());
__leave;
}
newAceIndex++;
}
}
//
// STEP 14: Add the access-allowed ACE to the new DACL.
// The new ACE added here will be in the correct position,
// immediately after all existing non-inherited ACEs.
//
if (!AddAccessAllowedAce(pNewACL, ACL_REVISION2, dwAccessMask,
pUserSID)) {
_tprintf(TEXT("AddAccessAllowedAce() failed. Error %d\n"),
GetLastError());
__leave;
}
//
// STEP 15: To conform to the new Windows 2000 preferred order,
// we will now copy the rest of inherited ACEs from the
// old DACL to the new DACL.
//
if (fDaclPresent && AclInfo.AceCount) {
for (;
CurrentAceIndex < AclInfo.AceCount;
CurrentAceIndex++) {
//
// STEP 16: Get an ACE.
//
if (!GetAce(pACL, CurrentAceIndex, &pTempAce)) {
_tprintf(TEXT("GetAce() failed. Error %d\n"),
GetLastError());
__leave;
}
//
// STEP 17: Add the ACE to the new ACL.
//
if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,
((PACE_HEADER) pTempAce)->AceSize)) {
_tprintf(TEXT("AddAce() failed. Error %d\n"),
GetLastError());
__leave;
}
}
}
//
// STEP 18: Set the new DACL to the new SD.
//
if (!SetSecurityDescriptorDacl(&newSD, TRUE, pNewACL,
FALSE)) {
_tprintf(TEXT("SetSecurityDescriptorDacl() failed. Error %d\n"),
GetLastError());
__leave;
}
//
// STEP 19: Copy the old security descriptor control flags
// regarding DACL automatic inheritance for Windows 2000 or
// later where SetSecurityDescriptorControl() API is available
// in advapi32.dll.
//
_SetSecurityDescriptorControl = (SetSecurityDescriptorControlFnPtr)
GetProcAddress(GetModuleHandle(TEXT("advapi32.dll")),
"SetSecurityDescriptorControl");
if (_SetSecurityDescriptorControl) {
SECURITY_DESCRIPTOR_CONTROL controlBitsOfInterest = 0;
SECURITY_DESCRIPTOR_CONTROL controlBitsToSet = 0;
SECURITY_DESCRIPTOR_CONTROL oldCon