本篇文章属于《518抽奖软件开发日志》系列文章的一部分。
我在开发《518抽奖软件》(www.518cj.net)的时候,偶尔会遇到正常文件夹下没读写权限,本来是应该有权限的。就是因为不知道怎么回事禁用了权限,删除禁用权限即可,代码如下,此代码对注册表项也适用。
- 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))
- {
- if (Tfuns::is_userAdmin() || Tfuns::is_runasAdmin())
- setOwner_admins(file);
- 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)
- {
- SetEntriesInAcl(0, NULL, 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))
- {
- if (Tfuns::is_userAdmin() || Tfuns::is_runasAdmin())
- setOwner_admins(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);
- }
-
-
- static BOOL SetPrivilege(HANDLE hToken, LPCTSTR name, BOOL bEnable)
- {
- TOKEN_PRIVILEGES tp = { 0 };
- LUID luid = { 0 };
-
- if (!LookupPrivilegeValue(NULL, name, &luid))
- return FALSE;
-
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Luid = luid;
- if (bEnable)
- tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- else
- tp.Privileges[0].Attributes = 0;
-
- return AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
- }
-
-
- static BOOL setOwner_admins(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;
-
- SE_OBJECT_TYPE type = SE_FILE_OBJECT;
- if (bReg) type = SE_REGISTRY_KEY;
-
- HANDLE hToken = NULL;
- OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
- if (!hToken)
- return FALSE;
-
- if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE))
- return FALSE;
-
- PSID pSID = NULL;
- SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
- if (!AllocateAndInitializeSid(&SIDAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSID))
- return FALSE;
-
- WCHAR obj[MAX_PATH] = { 0 };
- wcscpy(obj, file);
- DWORD r = SetNamedSecurityInfo(obj, type, OWNER_SECURITY_INFORMATION, pSID, NULL, NULL, NULL);
-
- if (pSID) FreeSid(pSID);
-
- if (r == ERROR_SUCCESS) return TRUE;
- else return FALSE;
- }