C++程序中Windows ACL的ACCESS_MASK权限相关技术问询
Hey there! Let's unpack your ACL and ACCESS_MASK questions clearly—this stuff can feel like navigating a maze at first, so I'll break it down step by step.
ACCESS_MASK Components First, let's clarify the three key parts of an ACCESS_MASK that you're confused about:
- Standard Rights: These are universal permissions that apply to all secure objects (files, registry keys, processes, etc.), not just files. Examples include:
DELETE: The right to delete the objectREAD_CONTROL: The right to read the object's ACLWRITE_DAC: The right to modify the object's discretionary ACL (DACL)- These are foundational rights that cross object types.
- Specific Rights: These are permissions tailored to a specific object type. For files, this includes things like
FILE_WRITE_DATA(write to the file),FILE_APPEND_DATA(add data to the end),FILE_DELETE_CHILD(delete files in a directory), etc. They're granular and tied directly to what you can do with a file specifically. - Generic Rights: Think of these as "shortcut" permission bundles designed to simplify coding. Instead of listing every specific/standard right you need, you can use a generic flag that maps to a pre-defined set. For files:
GENERIC_WRITEmaps toFILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES | SYNCHRONIZEGENERIC_ALLmaps to all possible rights (use this sparingly—it's overkill for most cases)- Generic rights are great for common scenarios, but if you need precise control, you'll want to use specific/standard rights instead.
Short answer: If you explicitly set generic permissions for the Everyone group (SID: S-1-1-0), then yes—seeing Everyone with write/delete access in the file properties is exactly what you asked for.
But wait: If your goal was to grant access to specific non-creator accounts (not every single account on the system), then this is a problem. That means your code is targeting the Everyone SID instead of the SID of your intended user/group. Double-check the SID you're using in your ACE (Access Control Entry) creation—if you don't want open access, swap Everyone for the target user/group's SID.
Here's a practical breakdown of what you need to do in C++:
- Retrieve the file's existing DACL: You need to work with the current access control list to avoid overwriting existing permissions entirely.
- Create a new ACE: Define the target user/group's SID, and specify the permissions you want (
FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE—orGENERIC_WRITE | DELETEif you want the full write bundle plus delete). - Add the ACE to the DACL: Append the new permission entry to the existing list.
- Apply the updated DACL to the file: Use Windows API functions to save the new security settings.
Quick Code Example
#include <windows.h> #include <aclapi.h> #include <sddl.h> #include <wchar.h> int wmain() { const LPCWSTR targetFile = L"C:\\your_file_here.txt"; PSID targetSid = nullptr; PSECURITY_DESCRIPTOR secDesc = nullptr; PACL existingDacl = nullptr; // Step 1: Get the SID for the target user/group (using Everyone as an example) if (!ConvertStringSidToSidW(L"S-1-1-0", &targetSid)) { wprintf(L"Failed to get SID: %lu\n", GetLastError()); goto cleanup; } // Step 2: Retrieve the file's current security descriptor (focus on DACL) if (GetNamedSecurityInfoW(targetFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nullptr, nullptr, &existingDacl, nullptr, &secDesc) != ERROR_SUCCESS) { wprintf(L"Failed to get security info: %lu\n", GetLastError()); goto cleanup; } // Step 3: Add an ACE granting WRITE + DELETE access to the target SID const ACCESS_MASK desiredPerms = GENERIC_WRITE | DELETE; if (!AddAccessAllowedAceEx(existingDacl, ACL_REVISION_DS, 0, desiredPerms, targetSid)) { wprintf(L"Failed to add ACE: %lu\n", GetLastError()); goto cleanup; } // Step 4: Apply the updated DACL back to the file if (SetNamedSecurityInfoW(targetFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nullptr, nullptr, existingDacl, nullptr) != ERROR_SUCCESS) { wprintf(L"Failed to set security info: %lu\n", GetLastError()); goto cleanup; } wprintf(L"Permissions updated successfully!\n"); cleanup: // Clean up allocated resources if (targetSid) LocalFree(targetSid); if (secDesc) LocalFree(secDesc); return 0; }
Key Notes
- Avoid over-permissioning: If you don't need every account to have access, replace the
EveryoneSID with the SID of your specific user/group (useLookupAccountNameWto get a SID from a username). - Error handling is critical: Windows ACL functions can fail for many reasons (e.g., insufficient permissions, invalid SIDs)—always check return codes.
- Inheritance: If your file is in a folder with inherited permissions, your new ACE might be overridden. Use
NO_INHERITANCEinAddAccessAllowedAceExif you want the permission to apply only to this file.
内容的提问来源于stack exchange,提问作者Simon Parker

