518抽奖软件之:打开文件读写权限代码
在开发518抽奖软件(www.)的时候,有的时候读写文件,极个别时候,发现文件权限有问题,例如设置了拒绝修改的权限。这个时候其实是有机会先修改权限,然后再读写的。这样如果是管理员权限的进程都可以修改权限,如果是文件的所有者也可以修改权限。SetNamedSecurityInfo 通过这个函数设置新的权限,在原来的权限的基础上,删除了多有拒绝类型的权限,并新增加了当前电脑用户的任意读写的权限。
具体代码如下:
void Tfuns::open_perm(const WCHAR* file)
{
BOOL bReg = FALSE;
if (StrStrI(file, L"USERS") == file ||
StrStrI(file, L"MACHINE") == file ||
StrStrI(file, L"CURRENT_USER") == file ||
StrStrI(file, L"CLASSES_ROOT") == file)
bReg = TRUE;
if (!bReg) SetFileAttributes(file, FILE_ATTRIBUTE_NORMAL);
PACL pOldDacl = NULL;
PACL pNewDacl = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
SE_OBJECT_TYPE type = SE_FILE_OBJECT;
if (bReg) type = SE_REGISTRY_KEY;
if (ERROR_SUCCESS != GetNamedSecurityInfo(file, type, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDacl, NULL, &pSD))
goto ERR;
{
WCHAR username[MAX_PATH] = { 0 };
DWORD sz = MAX_PATH;
GetUserName(username, &sz);
EXPLICIT_ACCESS ea = { 0 };
BuildExplicitAccessWithName(&ea, (LPTSTR)username, GENERIC_ALL, GRANT_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT);
SetEntriesInAcl(1, &ea, pOldDacl, &pNewDacl);
if (!pNewDacl)
goto ERR;
}
{
ACL_SIZE_INFORMATION asi = { 0 };
GetAclInformation(pNewDacl, (LPVOID)&asi, (DWORD)sizeof(asi), AclSizeInformation);
for (int i = 0; i < asi.AceCount; i++)
{
LPVOID ace = NULL;
GetAce(pNewDacl, i, &ace);
if (!ace) goto ERR;
if (((ACE_HEADER*)ace)->AceType == ACCESS_DENIED_ACE_TYPE ||
((ACE_HEADER*)ace)->AceType == ACCESS_DENIED_CALLBACK_ACE_TYPE ||
((ACE_HEADER*)ace)->AceType == ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE ||
((ACE_HEADER*)ace)->AceType == ACCESS_DENIED_OBJECT_ACE_TYPE)
{
if (!DeleteAce(pNewDacl, i))
goto ERR;
asi.AceCount--;
i--;
}
}
}
WCHAR obj[MAX_PATH] = { 0 };
wcscpy(obj, file);
if (ERROR_SUCCESS != SetNamedSecurityInfo(obj, type, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL))
goto ERR;
ERR:
if (pSD) LocalFree((HLOCAL)pSD);
if (pNewDacl) LocalFree((HLOCAL)pNewDacl);
}