BOOL bRetval = FALSE;HANDLE hToken = NULL; 
PSID pSIDAdmin = NULL;
PSID pSIDEveryone = NULL;
PACL pACL = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
const int NUM_ACES = 1;
EXPLICIT_ACCESS ea[NUM_ACES];
DWORD dwRes;// Specify the DACL to use.
// Create a SID for the Everyone group.
/* if (!AllocateAndInitializeSid(&SIDAuthWorld, 1,
SECURITY_WORLD_RID,
0,
0, 0, 0, 0, 0, 0,
&pSIDEveryone)) 
{
printf("AllocateAndInitializeSid (Everyone) error %u\n", GetLastError());
goto Cleanup;
}*/pSIDEveryone = GetSid(L"EveryOne", 0);// Create a SID for the BUILTIN\Administrators group.
/* if (!AllocateAndInitializeSid(&SIDAuthNT, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pSIDAdmin)) 
{
printf("AllocateAndInitializeSid (Admin) error %u\n", GetLastError());
goto Cleanup;
}*/ZeroMemory(&ea, NUM_ACES * sizeof(EXPLICIT_ACCESS));// Set read access for Everyone.
ea[0].grfAccessPermissions = GENERIC_ALL;
ea[0].grfAccessMode = REVOKE_ACCESS;
ea[0].grfInheritance = INHERITED_ACE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_INVALID;
ea[0].Trustee.ptstrName = (LPTSTR) pSIDEveryone;
if (ERROR_SUCCESS != SetEntriesInAcl(NUM_ACES,
ea,
NULL,
&pACL))
{
printf("Failed SetEntriesInAcl\n");
goto Cleanup;
}// Try to modify the object's DACL.
dwRes = SetNamedSecurityInfo(
lpszOwnFile, // name of the object
SE_FILE_OBJECT, // type of object
DACL_SECURITY_INFORMATION, // change only the object's DACL
NULL, NULL, // do not change owner or group
pACL, // DACL specified
NULL); // do not change SACLif (ERROR_SUCCESS == dwRes) 
{
printf("Successfully changed DACL\n");
bRetval = TRUE;
// No more processing needed.
goto Cleanup;
}
if (dwRes != ERROR_ACCESS_DENIED)
{
printf("First SetNamedSecurityInfo call failed: %u\n", dwRes); 
goto Cleanup;
}// If the preceding call failed because access was denied, 
// enable the SE_TAKE_OWNERSHIP_NAME privilege, create a SID for 
// the Administrators group, take ownership of the object, and 
// disable the privilege. Then try again to set the object's DACL.// Open a handle to the access token for the calling process.
if (!OpenProcessToken(GetCurrentProcess(), 
TOKEN_ADJUST_PRIVILEGES, 
&hToken)) 
{
printf("OpenProcessToken failed: %u\n", GetLastError()); 
goto Cleanup; 
} // Enable the SE_TAKE_OWNERSHIP_NAME privilege.
if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE)) 
{
printf("You must be logged on as Administrator.\n");
goto Cleanup; 
}// Set the owner in the object's security descriptor.
dwRes = SetNamedSecurityInfo(
lpszOwnFile, // name of the object
SE_FILE_OBJECT, // type of object
OWNER_SECURITY_INFORMATION, // change only the object's owner
pSIDAdmin, // SID of Administrator group
NULL,
NULL,
NULL); if (dwRes != ERROR_SUCCESS) 
{
printf("Could not set owner. Error: %u\n", dwRes); 
goto Cleanup;
}// Disable the SE_TAKE_OWNERSHIP_NAME privilege.
if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, FALSE)) 
{
printf("Failed SetPrivilege call unexpectedly.\n");
goto Cleanup;
}// Try again to modify the object's DACL, now that we are the owner.
dwRes = SetNamedSecurityInfo(
lpszOwnFile, // name of the object
SE_FILE_OBJECT, // type of object
DACL_SECURITY_INFORMATION, // change only the object's DACL
NULL, NULL, // do not change owner or group
pACL, // DACL specified
NULL); // do not change SACLif (dwRes == ERROR_SUCCESS)
{
printf("Successfully changed DACL\n");
bRetval = TRUE; 
}
else
{
printf("Second SetNamedSecurityInfo call failed: %u\n", dwRes); 
}Cleanup:if (pSIDAdmin)
FreeSid(pSIDAdmin); /* if (pSIDEveryone)
FreeSid(pSIDEveryone);*/ if (pACL)
LocalFree(pACL);if (hToken)
CloseHandle(hToken);上述方法只能删除自己添加的权限,不能删除从父目录继承过来的权限
该如何实现不从父目录继承权限呢????

解决方案 »

  1.   

    if you do not want to inherit permissions from the parent 
    directory, you need to use the SE_DACL_PROTECTED flag. if you want to save a lot of code, you can use SDDL (security 
    descriptor description language). The security descriptor creation 
    code can be replaced by a single call: ConvertStringSecurityDescriptorToSecurityDescriptor( 
            L"O:COD:(A;;FA;;;WD)", 
            SDDL_REVISION_1, 
            &pSD, 
            &dwSize 
            ); 
    SDDL is documented in MSDN.
      

  2.   

    CSid sidDenied;
    sidDenied.LoadAccount(L"ADMINISTRATORS");
    CDacl dacl;
    CSecurityDesc desc;
    dacl.RemoveAces(sidDenied);
    desc.SetDacl(dacl);
    desc.SetControl(SE_OWNER_DEFAULTED|
    SE_GROUP_DEFAULTED|
    SE_DACL_DEFAULTED|
    SE_SACL_PRESENT|
    SE_SACL_DEFAULTED|
    SE_DACL_AUTO_INHERIT_REQ|
    SE_SACL_AUTO_INHERIT_REQ|
    SE_SELF_RELATIVE, SE_DACL_PROTECTED);
    SetFileSecurity(lpszOwnFile,DACL_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION,&desc);
      

  3.   

    ATL 7.0增加了权限类 简单多了
    谢谢jiangsheng(蒋晟.Net[MVP])