• 打开文件、文件夹权限的C++源码 (去掉禁用权限)


    本篇文章属于《518抽奖软件开发日志》系列文章的一部分。

    我在开发《518抽奖软件》(www.518cj.net)的时候,偶尔会遇到正常文件夹下没读写权限,本来是应该有权限的。就是因为不知道怎么回事禁用了权限,删除禁用权限即可,代码如下,此代码对注册表项也适用。

    1. void Tfuns::open_perm(const WCHAR* file)
    2. {
    3. BOOL bReg = FALSE;
    4. if (StrStrI(file, L"USERS") == file ||
    5. StrStrI(file, L"MACHINE") == file ||
    6. StrStrI(file, L"CURRENT_USER") == file ||
    7. StrStrI(file, L"CLASSES_ROOT") == file)
    8. bReg = TRUE;
    9. if (!bReg) SetFileAttributes(file, FILE_ATTRIBUTE_NORMAL);
    10. PACL pOldDacl = NULL;
    11. PACL pNewDacl = NULL;
    12. PSECURITY_DESCRIPTOR pSD = NULL;
    13. SE_OBJECT_TYPE type = SE_FILE_OBJECT;
    14. if (bReg) type = SE_REGISTRY_KEY;
    15. if (ERROR_SUCCESS != GetNamedSecurityInfo(file, type, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDacl, NULL, &pSD))
    16. {
    17. if (Tfuns::is_userAdmin() || Tfuns::is_runasAdmin())
    18. setOwner_admins(file);
    19. if (ERROR_SUCCESS != GetNamedSecurityInfo(file, type, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDacl, NULL, &pSD))
    20. goto ERR;
    21. }
    22. {
    23. WCHAR username[MAX_PATH] = { 0 };
    24. DWORD sz = MAX_PATH;
    25. GetUserName(username, &sz);
    26. EXPLICIT_ACCESS ea = { 0 };
    27. // 增加允许权限
    28. BuildExplicitAccessWithName(&ea, (LPTSTR)username, GENERIC_ALL, GRANT_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT);
    29. SetEntriesInAcl(1, &ea, pOldDacl, &pNewDacl);
    30. if (!pNewDacl)
    31. {
    32. SetEntriesInAcl(0, NULL, pOldDacl, &pNewDacl);
    33. if (!pNewDacl)
    34. goto ERR;
    35. }
    36. }
    37. {
    38. ACL_SIZE_INFORMATION asi = { 0 };
    39. GetAclInformation(pNewDacl, (LPVOID)&asi, (DWORD)sizeof(asi), AclSizeInformation);
    40. for (int i = 0; i < asi.AceCount; i++)
    41. {
    42. LPVOID ace = NULL;
    43. GetAce(pNewDacl, i, &ace);
    44. if (!ace) goto ERR;
    45. // 删除禁用权限
    46. if (((ACE_HEADER*)ace)->AceType == ACCESS_DENIED_ACE_TYPE ||
    47. ((ACE_HEADER*)ace)->AceType == ACCESS_DENIED_CALLBACK_ACE_TYPE ||
    48. ((ACE_HEADER*)ace)->AceType == ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE ||
    49. ((ACE_HEADER*)ace)->AceType == ACCESS_DENIED_OBJECT_ACE_TYPE)
    50. {
    51. if (!DeleteAce(pNewDacl, i))
    52. goto ERR;
    53. asi.AceCount--;
    54. i--;
    55. }
    56. }
    57. }
    58. WCHAR obj[MAX_PATH] = { 0 };
    59. wcscpy(obj, file);
    60. if (ERROR_SUCCESS != SetNamedSecurityInfo(obj, type, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL))
    61. {
    62. if (Tfuns::is_userAdmin() || Tfuns::is_runasAdmin())
    63. setOwner_admins(file);
    64. if (ERROR_SUCCESS != SetNamedSecurityInfo(obj, type, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL))
    65. goto ERR;
    66. }
    67. ERR:
    68. if (pSD) LocalFree((HLOCAL)pSD);
    69. if (pNewDacl) LocalFree((HLOCAL)pNewDacl);
    70. }
    71. static BOOL SetPrivilege(HANDLE hToken, LPCTSTR name, BOOL bEnable)
    72. {
    73. TOKEN_PRIVILEGES tp = { 0 };
    74. LUID luid = { 0 };
    75. if (!LookupPrivilegeValue(NULL, name, &luid))
    76. return FALSE;
    77. tp.PrivilegeCount = 1;
    78. tp.Privileges[0].Luid = luid;
    79. if (bEnable)
    80. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    81. else
    82. tp.Privileges[0].Attributes = 0;
    83. return AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
    84. }
    85. static BOOL setOwner_admins(const WCHAR* file)
    86. {
    87. BOOL bReg = FALSE;
    88. if (StrStrI(file, L"USERS") == file ||
    89. StrStrI(file, L"MACHINE") == file ||
    90. StrStrI(file, L"CURRENT_USER") == file ||
    91. StrStrI(file, L"CLASSES_ROOT") == file)
    92. bReg = TRUE;
    93. SE_OBJECT_TYPE type = SE_FILE_OBJECT;
    94. if (bReg) type = SE_REGISTRY_KEY;
    95. HANDLE hToken = NULL;
    96. OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
    97. if (!hToken)
    98. return FALSE;
    99. if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE))
    100. return FALSE;
    101. PSID pSID = NULL;
    102. SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
    103. if (!AllocateAndInitializeSid(&SIDAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSID))
    104. return FALSE;
    105. WCHAR obj[MAX_PATH] = { 0 };
    106. wcscpy(obj, file);
    107. DWORD r = SetNamedSecurityInfo(obj, type, OWNER_SECURITY_INFORMATION, pSID, NULL, NULL, NULL);
    108. if (pSID) FreeSid(pSID);
    109. if (r == ERROR_SUCCESS) return TRUE;
    110. else return FALSE;
    111. }

  • 相关阅读:
    【数据结构学习笔记】18:线段树(单点修改)
    从零开始学 Docker-容器数据卷实战
    用手势识别来测试视力?试试用百度AI来实现想法
    LeetCode 438. 找到字符串中所有字母异位词
    浅浅研究模板字符串 ` `
    遥感图像应用:在低分辨率图像上实现洪水损害检测(迁移学习)
    linux 用户不在sudoers文件中,此事将被报告
    Pytorch学习笔记9——AutoEncoder
    数学建模-2022年亚太赛C题(含思路过程和代码)
    【SpringBoot】静态资源的访问
  • 原文地址:https://blog.csdn.net/WSG121212/article/details/132894543