X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fwimboot.c;h=9a61ba510bab13075ef60e40ceab270fcae47336;hb=c43944a2bc3991b6a7f7c16bb383233182ff46a5;hp=3562890d7636b08d4ea686df1fe5f9e26002deb7;hpb=58aff9150148ee210e7d96ad6748cbcc14a76f44;p=wimlib diff --git a/src/wimboot.c b/src/wimboot.c index 3562890d..9a61ba51 100644 --- a/src/wimboot.c +++ b/src/wimboot.c @@ -34,12 +34,13 @@ #endif #include "wimlib/win32_common.h" -#include "wimlib/win32.h" + #include "wimlib/assert.h" #include "wimlib/error.h" #include "wimlib/lookup_table.h" #include "wimlib/util.h" #include "wimlib/wimboot.h" +#include "wimlib/win32.h" #include "wimlib/wof.h" static HANDLE @@ -93,8 +94,8 @@ query_partition_and_disk_info(const wchar_t *path, h = open_file(vol_name, GENERIC_READ); if (h == INVALID_HANDLE_VALUE) { - ERROR("\"%ls\": Can't open volume device (err=%"PRIu32")", - vol_name, (u32)GetLastError()); + win32_error(GetLastError(), L"\"%ls\": Can't open volume device", + vol_name); ret = WIMLIB_ERR_OPEN; goto out; } @@ -102,8 +103,8 @@ query_partition_and_disk_info(const wchar_t *path, if (!query_device(h, IOCTL_DISK_GET_PARTITION_INFO_EX, part_info, sizeof(PARTITION_INFORMATION_EX))) { - ERROR("\"%ls\": Can't get partition info (err=%"PRIu32")", - vol_name, (u32)GetLastError()); + win32_error(GetLastError(), + L"\"%ls\": Can't get partition info", vol_name); ret = WIMLIB_ERR_READ; goto out; } @@ -121,8 +122,9 @@ query_partition_and_disk_info(const wchar_t *path, extents, extents_size)) break; if (GetLastError() != ERROR_MORE_DATA) { - ERROR("\"%ls\": Can't get volume extent info (err="PRIu32")", - vol_name, (u32)GetLastError()); + win32_error(GetLastError(), + L"\"%ls\": Can't get volume extent info", + vol_name); ret = WIMLIB_ERR_READ; goto out; } @@ -145,8 +147,8 @@ query_partition_and_disk_info(const wchar_t *path, h = open_file(disk_name, GENERIC_READ); if (h == INVALID_HANDLE_VALUE) { - ERROR("\"%ls\": Can't open disk device (err=%"PRIu32")", - disk_name, (u32)GetLastError()); + win32_error(GetLastError(), + L"\"%ls\": Can't open disk device", disk_name); ret = WIMLIB_ERR_OPEN; goto out; } @@ -164,8 +166,8 @@ query_partition_and_disk_info(const wchar_t *path, drive_info, drive_info_size)) break; if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { - ERROR("\"%ls\": Can't get disk info (err=%"PRIu32")", - disk_name, (u32)GetLastError()); + win32_error(GetLastError(), + L"\"%ls\": Can't get disk info", disk_name); ret = WIMLIB_ERR_READ; goto out; } @@ -290,23 +292,24 @@ write_wimoverlay_dat(const wchar_t *path, const void *contents, u32 size) h = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, NULL); if (h == INVALID_HANDLE_VALUE) { - set_errno_from_GetLastError(); - ERROR_WITH_ERRNO("\"%ls\": Can't open file for writing", path); + win32_error(GetLastError(), + L"\"%ls\": Can't open file for writing", path); return WIMLIB_ERR_OPEN; } + SetLastError(0); if (!WriteFile(h, contents, size, &bytes_written, NULL) || bytes_written != size) { - set_errno_from_GetLastError(); - ERROR_WITH_ERRNO("\"%ls\": Can't write file", path); + win32_error(GetLastError(), + L"\"%ls\": Can't write file", path); CloseHandle(h); return WIMLIB_ERR_WRITE; } if (!CloseHandle(h)) { - set_errno_from_GetLastError(); - ERROR_WITH_ERRNO("\"%ls\": Can't close handle", path); + win32_error(GetLastError(), + L"\"%ls\": Can't close handle", path); return WIMLIB_ERR_WRITE; } @@ -592,13 +595,11 @@ retry: err = err2; } } - set_errno_from_win32_error(err); - ERROR_WITH_ERRNO("\"%ls\": Can't open for reading", path); + win32_error(err, L"\"%ls\": Can't open for reading", path); return WIMLIB_ERR_OPEN; } if (!GetFileInformationByHandle(h, &info)) { - set_errno_from_GetLastError(); - ERROR_WITH_ERRNO("\"%ls\": Can't query metadata", path); + win32_error(GetLastError(), L"\"%ls\": Can't query metadata", path); CloseHandle(h); return WIMLIB_ERR_STAT; } @@ -612,11 +613,11 @@ retry: return WIMLIB_ERR_NOMEM; } + SetLastError(0); if (!ReadFile(h, contents, info.nFileSizeLow, &bytes_read, NULL) || bytes_read != info.nFileSizeLow) { - set_errno_from_GetLastError(); - ERROR_WITH_ERRNO("\"%ls\": Can't read data", path); + win32_error(GetLastError(), L"\"%ls\": Can't read data", path); CloseHandle(h); ret = WIMLIB_ERR_READ; goto out_free_contents; @@ -982,8 +983,8 @@ retry_ioctl: h = open_file(drive_path, GENERIC_WRITE); if (h == INVALID_HANDLE_VALUE) { - set_errno_from_GetLastError(); - ERROR_WITH_ERRNO("Failed to open \"%ls\"", drive_path + 4); + win32_error(GetLastError(), + L"Failed to open \"%ls\"", drive_path + 4); ret = WIMLIB_ERR_OPEN; goto out_free_in; } @@ -1005,17 +1006,14 @@ retry_ioctl: ret = WIMLIB_ERR_UNSUPPORTED; goto out_close_handle; } else { - set_errno_from_win32_error(err); - ERROR_WITH_ERRNO("Failed to add overlay source \"%ls\" " - "to volume \"%ls\" (err=0x%08"PRIx32")", - wim_path, drive_path + 4, (u32)err); + win32_error(err, L"Failed to add overlay source \"%ls\" " + "to volume \"%ls\"", wim_path, drive_path + 4); ret = WIMLIB_ERR_WIMBOOT; goto out_close_handle; } } if (bytes_returned != sizeof(data_source_id)) { - set_errno_from_win32_error(ERROR_INVALID_DATA); ret = WIMLIB_ERR_WIMBOOT; ERROR("Unexpected result size when adding " "overlay source \"%ls\" to volume \"%ls\"", @@ -1059,8 +1057,6 @@ out: * * @h * Open handle to the file, with GENERIC_WRITE access. - * @printable_name - * Printable representation of the path to the file. * @lte * Unnamed data stream of the file. * @data_source_id @@ -1071,28 +1067,29 @@ out: * %true if the WOF driver appears to be available and working; %false if * not. * - * Returns 0 on success, or a positive error code on failure. + * Returns %true on success, or %false on failure with GetLastError() set. */ -int +bool wimboot_set_pointer(HANDLE h, - const wchar_t *printable_name, const struct wim_lookup_table_entry *lte, u64 data_source_id, const u8 lookup_table_hash[SHA1_HASH_SIZE], bool wof_running) { DWORD bytes_returned; - DWORD err; if (wof_running) { /* The WOF driver is running. We can create the reparse point * using FSCTL_SET_EXTERNAL_BACKING. */ - + unsigned int max_retries = 4; struct { struct wof_external_info wof_info; struct wim_provider_external_info wim_info; } in; + retry: + memset(&in, 0, sizeof(in)); + in.wof_info.version = WOF_CURRENT_VERSION; in.wof_info.provider = WOF_PROVIDER_WIM; @@ -1106,7 +1103,22 @@ wimboot_set_pointer(HANDLE h, if (!DeviceIoControl(h, FSCTL_SET_EXTERNAL_BACKING, &in, sizeof(in), NULL, 0, &bytes_returned, NULL)) - goto fail; + { + /* Try to track down sporadic errors */ + if (wimlib_print_errors) { + WARNING("FSCTL_SET_EXTERNAL_BACKING failed (err=%u); data was %zu bytes:", + (u32)GetLastError(), sizeof(in)); + print_byte_field((const u8 *)&in, sizeof(in), wimlib_error_file); + putc('\n', wimlib_error_file); + } + if (--max_retries) { + WARNING("Retrying after 100ms..."); + Sleep(100); + goto retry; + } + WARNING("Too many retries; returning failure"); + return false; + } } else { /* The WOF driver is running. We need to create the reparse @@ -1144,7 +1156,7 @@ wimboot_set_pointer(HANDLE h, if (!DeviceIoControl(h, FSCTL_SET_REPARSE_POINT, &in, sizeof(in), NULL, 0, &bytes_returned, NULL)) - goto fail; + return false; /* We also need to create an unnamed data stream of the correct * size. Otherwise the file shows up as zero length. It can be @@ -1152,25 +1164,18 @@ wimboot_set_pointer(HANDLE h, * are unimportant. */ if (!DeviceIoControl(h, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &bytes_returned, NULL)) - goto fail; + return false; if (!SetFilePointerEx(h, (LARGE_INTEGER){ .QuadPart = lte->size}, NULL, FILE_BEGIN)) - goto fail; + return false; if (!SetEndOfFile(h)) - goto fail; + return false; } - return 0; - -fail: - err = GetLastError(); - set_errno_from_win32_error(err); - ERROR_WITH_ERRNO("\"%ls\": Couldn't set WIMBoot pointer data " - "(err=%"PRIu32")", printable_name, (u32)err); - return WIMLIB_ERR_WIMBOOT; + return true; } #endif /* __WIN32__ */