| 1287 | } activation_unlink_status_t; |
| 1288 | |
| 1289 | static activation_unlink_status_t activation_unlink_expected( |
| 1290 | const cbm_activation_transaction_t *transaction, const char *path, const char *name, |
| 1291 | const activation_file_identity_t *expected, bool allow_windows_deferred) { |
| 1292 | bool exists = false; |
| 1293 | if (!activation_path_matches(transaction, path, name, expected, &exists)) { |
| 1294 | return ACTIVATION_UNLINK_ERROR; |
| 1295 | } |
| 1296 | if (!exists) { |
| 1297 | return ACTIVATION_UNLINK_OK; |
| 1298 | } |
| 1299 | #ifdef _WIN32 |
| 1300 | wchar_t *wide = activation_utf8_to_wide(path); |
| 1301 | if (!wide) { |
| 1302 | return ACTIVATION_UNLINK_ERROR; |
| 1303 | } |
| 1304 | if (DeleteFileW(wide)) { |
| 1305 | free(wide); |
| 1306 | return ACTIVATION_UNLINK_OK; |
| 1307 | } |
| 1308 | DWORD error = GetLastError(); |
| 1309 | bool deferred = allow_windows_deferred && |
| 1310 | (error == ERROR_ACCESS_DENIED || error == ERROR_SHARING_VIOLATION || |
| 1311 | error == ERROR_LOCK_VIOLATION) && |
| 1312 | MoveFileExW(wide, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) != 0; |
| 1313 | free(wide); |
| 1314 | return deferred ? ACTIVATION_UNLINK_DEFERRED : ACTIVATION_UNLINK_ERROR; |
| 1315 | #else |
| 1316 | (void)allow_windows_deferred; |
| 1317 | int result; |
| 1318 | do { |
| 1319 | result = unlinkat(transaction->directory_fd, name, 0); |
| 1320 | } while (result != 0 && errno == EINTR); |
| 1321 | return result == 0 || errno == ENOENT ? ACTIVATION_UNLINK_OK : ACTIVATION_UNLINK_ERROR; |
| 1322 | #endif |
| 1323 | } |
| 1324 | |
| 1325 | static void activation_transaction_destroy(cbm_activation_transaction_t *transaction) { |
| 1326 | if (!transaction) { |
no test coverage detected