From: Eric Biggers Date: Fri, 30 Jan 2015 01:16:28 +0000 (-0600) Subject: Windows: improved error messages X-Git-Tag: v1.8.0~30 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=b8ebc57d493d7b6e660a50f7789fcb5451f5d77d Windows: improved error messages --- diff --git a/NEWS b/NEWS index ac957121..14c128b0 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,8 @@ Version 1.7.5-BETA: Fixed various issues related to capture/apply of EFS-encrypted files on Windows. + On Windows, some error and warning messages have been improved. + Version 1.7.4: The Windows binary distribution no longer contains third party DLLs. These dependencies are instead compiled directly into the libwim DLL. diff --git a/include/wimlib/win32_common.h b/include/wimlib/win32_common.h index 2fc12c1c..f27a2d71 100644 --- a/include/wimlib/win32_common.h +++ b/include/wimlib/win32_common.h @@ -17,9 +17,6 @@ set_errno_from_GetLastError(void); extern void set_errno_from_win32_error(DWORD err); -extern void -set_errno_from_nt_status(NTSTATUS status); - /* ntdll functions */ extern NTSTATUS (WINAPI *func_NtCreateFile)(PHANDLE FileHandle, @@ -159,4 +156,16 @@ win32_path_to_nt_path(const wchar_t *win32_path, UNICODE_STRING *nt_path); extern int win32_get_drive_path(const wchar_t *file_path, wchar_t drive_path[7]); +extern void +win32_warning(DWORD err, const wchar_t *format, ...) _cold_attribute; + +extern void +win32_error(DWORD err, const wchar_t *format, ...) _cold_attribute; + +extern void +winnt_warning(NTSTATUS status, const wchar_t *format, ...) _cold_attribute; + +extern void +winnt_error(NTSTATUS status, const wchar_t *format, ...) _cold_attribute; + #endif /* _WIMLIB_WIN32_COMMON_H */ diff --git a/src/wimboot.c b/src/wimboot.c index 2b6a2415..9a61ba51 100644 --- a/src/wimboot.c +++ b/src/wimboot.c @@ -94,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; } @@ -103,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; } @@ -122,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; } @@ -146,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; } @@ -165,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; } @@ -291,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; } @@ -593,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; } @@ -613,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; @@ -983,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; } @@ -1006,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\"", @@ -1080,7 +1077,6 @@ wimboot_set_pointer(HANDLE h, bool wof_running) { DWORD bytes_returned; - DWORD err; if (wof_running) { /* The WOF driver is running. We can create the reparse point diff --git a/src/win32_apply.c b/src/win32_apply.c index 966e957d..630a77f1 100644 --- a/src/win32_apply.c +++ b/src/win32_apply.c @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2013, 2014 Eric Biggers + * Copyright (C) 2013, 2014, 2015 Eric Biggers * * This file is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free @@ -178,11 +178,9 @@ get_vol_flags(const wchar_t *target, DWORD *vol_flags_ret, vol_flags_ret, filesystem_name, ARRAY_LEN(filesystem_name))) { - DWORD err = GetLastError(); - set_errno_from_win32_error(err); - WARNING_WITH_ERRNO("Failed to get volume information for " - "\"%ls\" (err=%"PRIu32")", - target, (u32)err); + win32_warning(GetLastError(), + L"Failed to get volume information for \"%ls\"", + target); return; } @@ -482,10 +480,8 @@ set_external_backing(HANDLE h, struct wim_inode *inode, struct win32_apply_ctx * const DWORD err = GetLastError(); build_extraction_path(inode_first_extraction_dentry(inode), ctx); - set_errno_from_win32_error(err); - ERROR_WITH_ERRNO("\"%ls\": Couldn't set WIMBoot " - "pointer data (err=%"PRIu32")", - current_path(ctx), (u32)err); + win32_error(err, L"\"%ls\": Couldn't set WIMBoot pointer data", + current_path(ctx)); return WIMLIB_ERR_WIMBOOT; } return 0; @@ -593,10 +589,9 @@ out_unload_key: out_check_res: if (res) { /* Warning only. */ - set_errno_from_win32_error(res); - WARNING_WITH_ERRNO("Failed to set \\Setup: dword \"WimBoot\"=1 value " - "in registry hive \"%ls\" (err=%"PRIu32")", - ctx->pathbuf.Buffer, (u32)res); + win32_warning(res, L"Failed to set \\Setup: dword \"WimBoot\"=1 " + "value in registry hive \"%ls\"", + ctx->pathbuf.Buffer); } out: return 0; @@ -790,10 +785,8 @@ open_target_directory(struct win32_apply_ctx *ctx) NULL, 0); if (!NT_SUCCESS(status)) { - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("Can't open or create directory \"%ls\" " - "(status=0x%08"PRIx32")", - ctx->common.target, (u32)status); + winnt_error(status, L"Can't open or create directory \"%ls\"", + ctx->common.target); return WIMLIB_ERR_OPENDIR; } ctx->attr.RootDirectory = ctx->h_target; @@ -923,11 +916,8 @@ adjust_compression_attribute(HANDLE h, const struct wim_dentry *dentry, if (NT_SUCCESS(status)) return 0; - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("Can't %s compression attribute on \"%ls\" " - "(status=0x%08"PRIx32")", - (compressed ? "set" : "clear"), - current_path(ctx), status); + winnt_error(status, L"Can't %s compression attribute on \"%ls\"", + (compressed ? "set" : "clear"), current_path(ctx)); return WIMLIB_ERR_SET_ATTRIBUTES; } @@ -963,8 +953,9 @@ try_to_enable_short_names(const wchar_t *volume) return true; fail: - WARNING("Failed to enable short name support on %ls " - "(err=%"PRIu32")", volume + 4, (u32)GetLastError()); + win32_warning(GetLastError(), + L"Failed to enable short name support on %ls", + volume + 4); return false; } @@ -996,8 +987,7 @@ remove_conflicting_short_name(const struct wim_dentry *dentry, struct win32_appl FILE_SHARE_VALID_FLAGS, FILE_OPEN_REPARSE_POINT | FILE_OPEN_FOR_BACKUP_INTENT); if (!NT_SUCCESS(status)) { - WARNING("Can't open \"%ls\" (status=0x%08"PRIx32")", - current_path(ctx), (u32)status); + winnt_warning(status, L"Can't open \"%ls\"", current_path(ctx)); goto out; } @@ -1136,13 +1126,7 @@ retry: return 0; } - if (status == STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME) { - ERROR("Can't set short name when short " - "names are not enabled on the volume!"); - } else { - ERROR("Can't set short name on \"%ls\" (status=0x%08"PRIx32")", - current_path(ctx), (u32)status); - } + winnt_error(status, L"Can't set short name on \"%ls\"", current_path(ctx)); return WIMLIB_ERR_SET_SHORT_NAME; } @@ -1216,10 +1200,8 @@ delete_file_or_stream(struct win32_apply_ctx *ctx) FILE_NON_DIRECTORY_FILE, ctx); if (unlikely(!NT_SUCCESS(status))) { - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("Can't open \"%ls\" for deletion " - "(status=0x%08"PRIx32")", - current_path(ctx), (u32)status); + winnt_error(status, L"Can't open \"%ls\" for deletion", + current_path(ctx)); return WIMLIB_ERR_OPEN; } @@ -1244,10 +1226,9 @@ retry: FILE_NON_DIRECTORY_FILE, ctx); if (!NT_SUCCESS(status)) { - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("Can't open \"%ls\" to reset attributes " - "(status=0x%08"PRIx32")", - current_path(ctx), (u32)status); + winnt_error(status, + L"Can't open \"%ls\" to reset attributes", + current_path(ctx)); return WIMLIB_ERR_OPEN; } memset(&basic_info, 0, sizeof(basic_info)); @@ -1257,19 +1238,16 @@ retry: sizeof(basic_info), FileBasicInformation); if (!NT_SUCCESS(status)) { - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("Can't reset file attributes on \"%ls\" " - "(status=0x%08"PRIx32")", - current_path(ctx), (u32)status); + winnt_error(status, + L"Can't reset file attributes on \"%ls\"", + current_path(ctx)); (*func_NtClose)(h); return WIMLIB_ERR_SET_ATTRIBUTES; } retried = true; goto retry; } - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("Can't delete \"%ls\" (status=0x%08"PRIx32")", - current_path(ctx), (u32)status); + winnt_error(status, L"Can't delete \"%ls\"", current_path(ctx)); return WIMLIB_ERR_OPEN; } @@ -1311,9 +1289,7 @@ retry: retried = true; goto retry; } - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("Can't create \"%ls\" (status=0x%08"PRIx32")", - current_path(ctx), (u32)status); + winnt_error(status, L"Can't create \"%ls\"", current_path(ctx)); return WIMLIB_ERR_OPEN; } @@ -1387,10 +1363,8 @@ create_directory(const struct wim_dentry *dentry, FILE_ATTRIBUTE_SYSTEM, FILE_OPEN_IF, FILE_DIRECTORY_FILE, dentry, ctx); if (!NT_SUCCESS(status)) { - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("Can't create directory \"%ls\" " - "(status=0x%08"PRIx32")", - current_path(ctx), (u32)status); + winnt_error(status, L"Can't create directory \"%ls\"", + current_path(ctx)); return WIMLIB_ERR_MKDIR; } @@ -1517,8 +1491,8 @@ create_link(HANDLE h, const struct wim_dentry *dentry, FileLinkInformation); if (NT_SUCCESS(status)) return 0; - ERROR("Failed to create link \"%ls\" (status=0x%08"PRIx32")", - current_path(ctx), (u32)status); + winnt_error(status, L"Failed to create link \"%ls\"", + current_path(ctx)); return WIMLIB_ERR_LINK; } else { HANDLE h2; @@ -1737,10 +1711,8 @@ begin_extract_stream_instance(const struct wim_lookup_table_entry *stream, FILE_SYNCHRONOUS_IO_NONALERT, ctx); if (!NT_SUCCESS(status)) { - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("Can't open \"%ls\" for writing " - "(status=0x%08"PRIx32")", - current_path(ctx), (u32)status); + winnt_error(status, L"Can't open \"%ls\" for writing", + current_path(ctx)); return WIMLIB_ERR_OPEN; } @@ -1797,10 +1769,8 @@ do_set_reparse_data(const struct wim_dentry *dentry, } fail: - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("Can't set reparse data on \"%ls\" " - "(status=0x%08"PRIx32")", - current_path(ctx), (u32)status); + winnt_error(status, L"Can't set reparse data on \"%ls\"", + current_path(ctx)); return WIMLIB_ERR_SET_REPARSE_DATA; } @@ -2011,9 +1981,8 @@ retry: build_extraction_path(dentry, ctx); if (err != ERROR_SUCCESS) { - set_errno_from_win32_error(err); - ERROR_WITH_ERRNO("Can't open \"%ls\" for encrypted import " - "(err=%"PRIu32")", current_path(ctx), (u32)err); + win32_error(err, L"Can't open \"%ls\" for encrypted import", + current_path(ctx)); return WIMLIB_ERR_OPEN; } @@ -2024,9 +1993,8 @@ retry: CloseEncryptedFileRaw(rawctx); if (err != ERROR_SUCCESS) { - set_errno_from_win32_error(err); - ERROR_WITH_ERRNO("Can't import encrypted file \"%ls\" " - "(err=%"PRIu32")", current_path(ctx), (u32)err); + win32_error(err, L"Can't import encrypted file \"%ls\"", + current_path(ctx)); return WIMLIB_ERR_WRITE; } @@ -2108,10 +2076,7 @@ extract_chunk(const void *chunk, size_t size, void *_ctx) &ctx->iosb, bufptr, count, NULL, NULL); if (!NT_SUCCESS(status)) { - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("Error writing data to target " - "volume (status=0x%08"PRIx32")", - (u32)status); + winnt_error(status, L"Error writing data to target volume"); return WIMLIB_ERR_WRITE; } bufptr += ctx->iosb.Information; @@ -2355,10 +2320,9 @@ do_apply_metadata_to_file(HANDLE h, const struct wim_inode *inode, if (!NT_SUCCESS(status) && (ctx->common.extract_flags & WIMLIB_EXTRACT_FLAG_STRICT_ACLS)) { - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("Can't set security descriptor " - "on \"%ls\" (status=0x%08"PRIx32")", - current_path(ctx), (u32)status); + winnt_error(status, + L"Can't set security descriptor on \"%ls\"", + current_path(ctx)); return WIMLIB_ERR_SET_SECURITY; } } @@ -2386,10 +2350,8 @@ do_apply_metadata_to_file(HANDLE h, const struct wim_inode *inode, && !(status == STATUS_INVALID_PARAMETER && dentry_is_root(inode_first_extraction_dentry(inode)))) { - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("Can't set basic metadata on \"%ls\" " - "(status=0x%08"PRIx32")", - current_path(ctx), (u32)status); + winnt_error(status, L"Can't set basic metadata on \"%ls\"", + current_path(ctx)); return WIMLIB_ERR_SET_ATTRIBUTES; } @@ -2431,10 +2393,8 @@ apply_metadata_to_file(const struct wim_dentry *dentry, continue; } } - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("Can't open \"%ls\" to set metadata " - "(status=0x%08"PRIx32")", - current_path(ctx), (u32)status); + winnt_error(status, L"Can't open \"%ls\" to set metadata", + current_path(ctx)); return WIMLIB_ERR_OPEN; } diff --git a/src/win32_capture.c b/src/win32_capture.c index e89d098c..8b7171c2 100644 --- a/src/win32_capture.c +++ b/src/win32_capture.c @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2013, 2014 Eric Biggers + * Copyright (C) 2013, 2014, 2015 Eric Biggers * * This file is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free @@ -27,8 +27,6 @@ # include "config.h" #endif -#include - #include "wimlib/win32_common.h" #include "wimlib/assert.h" @@ -123,10 +121,8 @@ read_winnt_file_prefix(const struct wim_lookup_table_entry *lte, u64 size, status = winnt_openat(NULL, path, wcslen(path), FILE_READ_DATA | SYNCHRONIZE, &h); if (!NT_SUCCESS(status)) { - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("\"%ls\": Can't open for reading " - "(status=0x%08"PRIx32")", - printable_path(path), (u32)status); + winnt_error(status, L"\"%ls\": Can't open for reading", + printable_path(path)); return WIMLIB_ERR_OPEN; } @@ -142,10 +138,8 @@ read_winnt_file_prefix(const struct wim_lookup_table_entry *lte, u64 size, status = (*func_NtReadFile)(h, NULL, NULL, NULL, &iosb, buf, count, NULL, NULL); if (!NT_SUCCESS(status)) { - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("\"%ls\": Error reading data " - "(status=0x%08"PRIx32")", - printable_path(path), (u32)status); + winnt_error(status, L"\"%ls\": Error reading data", + printable_path(path)); ret = WIMLIB_ERR_READ; break; } @@ -181,8 +175,8 @@ win32_encrypted_export_cb(unsigned char *data, void *_ctx, unsigned long len) ret = (*ctx->read_prefix_cb)(data, bytes_to_consume, ctx->read_prefix_ctx); if (ret) { ctx->wimlib_err_code = ret; - /* Shouldn't matter what error code is returned here, as long as - * it isn't ERROR_SUCCESS. */ + /* It doesn't matter what error code is returned here, as long + * as it isn't ERROR_SUCCESS. */ return ERROR_READ_FAULT; } ctx->bytes_remaining -= bytes_to_consume; @@ -206,21 +200,21 @@ read_win32_encrypted_file_prefix(const struct wim_lookup_table_entry *lte, err = OpenEncryptedFileRaw(lte->file_on_disk, 0, &file_ctx); if (err != ERROR_SUCCESS) { - set_errno_from_win32_error(err); - ERROR_WITH_ERRNO("Failed to open encrypted file \"%ls\" " - "for raw read", - printable_path(lte->file_on_disk)); + win32_error(err, + L"Failed to open encrypted file \"%ls\" for raw read", + printable_path(lte->file_on_disk)); return WIMLIB_ERR_OPEN; } err = ReadEncryptedFileRaw(win32_encrypted_export_cb, &export_ctx, file_ctx); if (err != ERROR_SUCCESS) { - set_errno_from_win32_error(err); - ERROR_WITH_ERRNO("Failed to read encrypted file \"%ls\"", - printable_path(lte->file_on_disk)); ret = export_ctx.wimlib_err_code; - if (ret == 0) + if (ret == 0) { + win32_error(err, + L"Failed to read encrypted file \"%ls\"", + printable_path(lte->file_on_disk)); ret = WIMLIB_ERR_READ; + } } else if (export_ctx.bytes_remaining != 0) { ERROR("Only could read %"PRIu64" of %"PRIu64" bytes from " "encrypted file \"%ls\"", @@ -465,10 +459,8 @@ winnt_recurse_directory(HANDLE h, } if (unlikely(status != STATUS_NO_MORE_FILES)) { - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("\"%ls\": Can't read directory " - "(status=0x%08"PRIx32")", - printable_path(full_path), (u32)status); + winnt_error(status, L"\"%ls\": Can't read directory", + printable_path(full_path)); ret = WIMLIB_ERR_READ; } out_free_buf: @@ -759,12 +751,14 @@ winnt_get_reparse_data(HANDLE h, const wchar_t *path, NULL, 0, rpbuf, REPARSE_POINT_MAX_SIZE, &bytes_returned, NULL)) { - set_errno_from_GetLastError(); + win32_error(GetLastError(), L"\"%ls\": Can't get reparse data", + printable_path(path)); return WIMLIB_ERR_READ; } if (unlikely(bytes_returned < 8)) { - errno = EINVAL; + ERROR("\"%ls\": Reparse point data is invalid", + printable_path(path)); return WIMLIB_ERR_INVALID_REPARSE_DATA; } @@ -801,18 +795,18 @@ win32_get_encrypted_file_size(const wchar_t *path, u64 *size_ret) err = OpenEncryptedFileRaw(path, 0, &file_ctx); if (err != ERROR_SUCCESS) { - set_errno_from_win32_error(err); - ERROR_WITH_ERRNO("Failed to open encrypted file \"%ls\" " - "for raw read", printable_path(path)); + win32_error(err, + L"Failed to open encrypted file \"%ls\" for raw read", + printable_path(path)); return WIMLIB_ERR_OPEN; } *size_ret = 0; err = ReadEncryptedFileRaw(win32_tally_encrypted_size_cb, size_ret, file_ctx); if (err != ERROR_SUCCESS) { - set_errno_from_win32_error(err); - ERROR_WITH_ERRNO("Failed to read raw encrypted data from " - "\"%ls\"", printable_path(path)); + win32_error(err, + L"Failed to read raw encrypted data from \"%ls\"", + printable_path(path)); ret = WIMLIB_ERR_READ; } else { ret = 0; @@ -1044,10 +1038,9 @@ winnt_scan_streams(HANDLE h, const wchar_t *path, size_t path_nchars, case STATUS_INVALID_INFO_CLASS: goto unnamed_only; default: - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("\"%ls\": Failed to query stream " - "information (status=0x%08"PRIx32")", - printable_path(path), (u32)status); + winnt_error(status, + L"\"%ls\": Failed to query stream information", + printable_path(path)); ret = WIMLIB_ERR_READ; goto out_free_buf; } @@ -1155,19 +1148,12 @@ retry_open: goto retry_open; } - if (status == STATUS_FVE_LOCKED_VOLUME) { - ERROR("\"%ls\": Can't open file " - "(encrypted volume has not been unlocked)", - printable_path(full_path)); + winnt_error(status, L"\"%ls\": Can't open file", + printable_path(full_path)); + if (status == STATUS_FVE_LOCKED_VOLUME) ret = WIMLIB_ERR_FVE_LOCKED_VOLUME; - goto out; - } - - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("\"%ls\": Can't open file " - "(status=0x%08"PRIx32")", - printable_path(full_path), (u32)status); - ret = WIMLIB_ERR_OPEN; + else + ret = WIMLIB_ERR_OPEN; goto out; } @@ -1183,10 +1169,9 @@ retry_open: if (unlikely(!NT_SUCCESS(status) && status != STATUS_BUFFER_OVERFLOW)) { - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("\"%ls\": Can't get file information " - "(status=0x%08"PRIx32")", - printable_path(full_path), (u32)status); + winnt_error(status, + L"\"%ls\": Can't get file information", + printable_path(full_path)); ret = WIMLIB_ERR_STAT; goto out; } @@ -1223,11 +1208,9 @@ retry_open: { vol_flags = attr_info.FileSystemAttributes; } else { - set_errno_from_nt_status(status); - WARNING_WITH_ERRNO("\"%ls\": Can't get volume attributes " - "(status=0x%08"PRIx32")", - printable_path(full_path), - (u32)status); + winnt_warning(status, + L"\"%ls\": Can't get volume attributes", + printable_path(full_path)); vol_flags = 0; } @@ -1249,11 +1232,8 @@ retry_open: { params->capture_root_dev = vol_info.VolumeSerialNumber; } else { - set_errno_from_nt_status(status); - WARNING_WITH_ERRNO("\"%ls\": Can't get volume ID " - "(status=0x%08"PRIx32")", - printable_path(full_path), - (u32)status); + winnt_warning(status, L"\"%ls\": Can't get volume ID", + printable_path(full_path)); params->capture_root_dev = 0; } } @@ -1273,8 +1253,6 @@ retry_open: not_rpfixed = 1; break; default: - ERROR_WITH_ERRNO("\"%ls\": Can't get reparse data", - printable_path(full_path)); goto out; } } @@ -1337,11 +1315,9 @@ retry_open: params->sd_set, stats, params->add_flags); if (!NT_SUCCESS(status)) { - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("\"%ls\": Can't read security " - "descriptor (status=0x%08"PRIx32")", - printable_path(full_path), - (u32)status); + winnt_error(status, + L"\"%ls\": Can't read security descriptor", + printable_path(full_path)); ret = WIMLIB_ERR_STAT; goto out; } @@ -1405,11 +1381,9 @@ retry_open: FILE_LIST_DIRECTORY | SYNCHRONIZE, &h); if (!NT_SUCCESS(status)) { - set_errno_from_nt_status(status); - ERROR_WITH_ERRNO("\"%ls\": Can't re-open file " - "(status=0x%08"PRIx32")", - printable_path(full_path), - (u32)status); + winnt_error(status, + L"\"%ls\": Can't re-open file", + printable_path(full_path)); ret = WIMLIB_ERR_OPEN; goto out; } diff --git a/src/win32_common.c b/src/win32_common.c index f66b33a9..bc92fe33 100644 --- a/src/win32_common.c +++ b/src/win32_common.c @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2013, 2014 Eric Biggers + * Copyright (C) 2013, 2014, 2015 Eric Biggers * * This file is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free @@ -313,12 +313,6 @@ set_errno_from_GetLastError(void) set_errno_from_win32_error(GetLastError()); } -void -set_errno_from_nt_status(NTSTATUS status) -{ - set_errno_from_win32_error((*func_RtlNtStatusToDosError)(status)); -} - static bool win32_modify_privilege(const wchar_t *privilege, bool enable) { @@ -664,5 +658,106 @@ win32_get_drive_path(const wchar_t *file_path, wchar_t drive_path[7]) return 0; } +static void +windows_msg(u32 code, const wchar_t *format, va_list va, + bool is_ntstatus, bool is_error) +{ + wchar_t _buf[STACK_MAX / 8]; + wchar_t *buf = _buf; + size_t buflen = ARRAY_LEN(_buf); + size_t ret; + size_t n; + +retry: + n = vsnwprintf(buf, buflen, format, va); + + if (n >= buflen) + goto realloc; + + n += snwprintf(&buf[n], buflen - n, + (is_ntstatus ? + L" (status=%08"PRIx32"): " : + L" (err=%"PRIu32"): "), + code); + + if (n >= buflen) + goto realloc; + + ret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + is_ntstatus ? (*func_RtlNtStatusToDosError)(code) : code, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + &buf[n], + buflen - n, + NULL); + n += ret; + + if (n >= buflen || (ret == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER)) + goto realloc; + + if (buf[n - 1] == L'\n') + buf[--n] = L'\0'; + if (buf[n - 1] == L'\r') + buf[--n] = L'\0'; + if (buf[n - 1] == L'.') + buf[--n] = L'\0'; + + if (is_error) + ERROR("%ls", buf); + else + WARNING("%ls", buf); + if (buf != _buf) + FREE(buf); + return; + +realloc: + if (buf != _buf) + FREE(buf); + buflen *= 2; + buf = MALLOC(buflen * sizeof(buf[0])); + if (buf) + goto retry; + ERROR("Ran out of memory while building error message!!!"); +} + +void +win32_warning(DWORD err, const wchar_t *format, ...) +{ + va_list va; + + va_start(va, format); + windows_msg(err, format, va, false, false); + va_end(va); +} + +void +win32_error(DWORD err, const wchar_t *format, ...) +{ + va_list va; + + va_start(va, format); + windows_msg(err, format, va, false, true); + va_end(va); +} + +void +winnt_warning(NTSTATUS status, const wchar_t *format, ...) +{ + va_list va; + + va_start(va, format); + windows_msg(status, format, va, true, false); + va_end(va); +} + +void +winnt_error(NTSTATUS status, const wchar_t *format, ...) +{ + va_list va; + + va_start(va, format); + windows_msg(status, format, va, true, true); + va_end(va); +} #endif /* __WIN32__ */