| 366 | #endif |
| 367 | |
| 368 | static int yaml_lock_acquire(const char *path, yaml_config_lock_t *lock) { |
| 369 | memset(lock, 0, sizeof(*lock)); |
| 370 | #ifdef _WIN32 |
| 371 | lock->handle = INVALID_HANDLE_VALUE; |
| 372 | #else |
| 373 | lock->descriptor = -1; |
| 374 | #endif |
| 375 | if (yaml_build_lock_path(path, &lock->path) != 0) { |
| 376 | return YAML_ERROR; |
| 377 | } |
| 378 | |
| 379 | #ifdef _WIN32 |
| 380 | wchar_t *wide_path = cbm_utf8_to_wide(lock->path); |
| 381 | if (!wide_path) { |
| 382 | free(lock->path); |
| 383 | lock->path = NULL; |
| 384 | return YAML_ERROR; |
| 385 | } |
| 386 | if (!CreateDirectoryW(wide_path, NULL)) { |
| 387 | free(wide_path); |
| 388 | free(lock->path); |
| 389 | lock->path = NULL; |
| 390 | return YAML_ERROR; |
| 391 | } |
| 392 | HANDLE handle = CreateFileW(wide_path, DELETE | FILE_READ_ATTRIBUTES, |
| 393 | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, |
| 394 | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); |
| 395 | if (handle == INVALID_HANDLE_VALUE) { |
| 396 | (void)RemoveDirectoryW(wide_path); |
| 397 | free(wide_path); |
| 398 | free(lock->path); |
| 399 | lock->path = NULL; |
| 400 | return YAML_ERROR; |
| 401 | } |
| 402 | BY_HANDLE_FILE_INFORMATION created_info; |
| 403 | if (!GetFileInformationByHandle(handle, &created_info) || |
| 404 | (created_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 || |
| 405 | (created_info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { |
| 406 | yaml_remove_open_lock_directory(handle); |
| 407 | free(wide_path); |
| 408 | free(lock->path); |
| 409 | lock->path = NULL; |
| 410 | return YAML_ERROR; |
| 411 | } |
| 412 | #ifdef CBM_YAML_ENABLE_TEST_API |
| 413 | if (yaml_lock_postcreate_test_hook) { |
| 414 | yaml_lock_postcreate_test_hook(lock->path, yaml_lock_postcreate_test_context); |
| 415 | } |
| 416 | #endif |
| 417 | BY_HANDLE_FILE_INFORMATION info; |
| 418 | if (!GetFileInformationByHandle(handle, &info) || |
| 419 | (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 || |
| 420 | (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0 || |
| 421 | info.dwVolumeSerialNumber != created_info.dwVolumeSerialNumber || |
| 422 | info.nFileIndexHigh != created_info.nFileIndexHigh || |
| 423 | info.nFileIndexLow != created_info.nFileIndexLow) { |
| 424 | yaml_remove_open_lock_directory(handle); |
| 425 | free(wide_path); |
no test coverage detected