| 1102 | } |
| 1103 | |
| 1104 | int ArchWindowsFileAccess(const char* path, uint32_t dwAccessMask) |
| 1105 | { |
| 1106 | // We take the arg as uint32_t to avoid including Windows.h in our .h. |
| 1107 | DWORD accessMask = dwAccessMask; |
| 1108 | |
| 1109 | std::wstring wpath{ ArchWindowsUtf8ToUtf16(path) }; |
| 1110 | |
| 1111 | const SECURITY_INFORMATION securityInfo = OWNER_SECURITY_INFORMATION | |
| 1112 | GROUP_SECURITY_INFORMATION | |
| 1113 | DACL_SECURITY_INFORMATION; |
| 1114 | |
| 1115 | // Get the SECURITY_DESCRIPTOR size. |
| 1116 | DWORD length = 0; |
| 1117 | if (!GetFileSecurityW(wpath.c_str(), securityInfo, NULL, 0, &length)) { |
| 1118 | if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { |
| 1119 | return Arch_FileAccessError(); |
| 1120 | } |
| 1121 | } |
| 1122 | |
| 1123 | // Get the SECURITY_DESCRIPTOR. |
| 1124 | std::unique_ptr<unsigned char[]> buffer(new unsigned char[length]); |
| 1125 | PSECURITY_DESCRIPTOR security = (PSECURITY_DESCRIPTOR)buffer.get(); |
| 1126 | if (!GetFileSecurityW( |
| 1127 | wpath.c_str(), securityInfo, security, length, &length)) { |
| 1128 | return Arch_FileAccessError(); |
| 1129 | } |
| 1130 | |
| 1131 | |
| 1132 | HANDLE token; |
| 1133 | DWORD desiredAccess = TOKEN_IMPERSONATE | TOKEN_QUERY | |
| 1134 | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ; |
| 1135 | if (!OpenThreadToken(GetCurrentThread(), desiredAccess, TRUE, &token)) |
| 1136 | { |
| 1137 | if (!OpenProcessToken(GetCurrentProcess(), desiredAccess, &token)) |
| 1138 | { |
| 1139 | CloseHandle(token); |
| 1140 | errno = EACCES; |
| 1141 | return -1; |
| 1142 | } |
| 1143 | } |
| 1144 | |
| 1145 | bool result = false; |
| 1146 | HANDLE duplicateToken; |
| 1147 | if (DuplicateToken(token, SecurityImpersonation, &duplicateToken)) |
| 1148 | { |
| 1149 | PRIVILEGE_SET privileges = {0}; |
| 1150 | DWORD grantedAccess = 0; |
| 1151 | DWORD privilegesLength = sizeof(privileges); |
| 1152 | BOOL accessStatus = FALSE; |
| 1153 | |
| 1154 | GENERIC_MAPPING mapping; |
| 1155 | mapping.GenericRead = FILE_GENERIC_READ; |
| 1156 | mapping.GenericWrite = FILE_GENERIC_WRITE; |
| 1157 | mapping.GenericExecute = FILE_GENERIC_EXECUTE; |
| 1158 | mapping.GenericAll = FILE_ALL_ACCESS; |
| 1159 | |
| 1160 | MapGenericMask(&accessMask, &mapping); |
| 1161 |
no test coverage detected