Windows: improved error messages
authorEric Biggers <ebiggers3@gmail.com>
Fri, 30 Jan 2015 01:16:28 +0000 (19:16 -0600)
committerEric Biggers <ebiggers3@gmail.com>
Fri, 30 Jan 2015 03:50:13 +0000 (21:50 -0600)
NEWS
include/wimlib/win32_common.h
src/wimboot.c
src/win32_apply.c
src/win32_capture.c
src/win32_common.c

diff --git a/NEWS b/NEWS
index ac95712..14c128b 100644 (file)
--- 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.
index 2fc12c1..f27a2d7 100644 (file)
@@ -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 */
index 2b6a241..9a61ba5 100644 (file)
@@ -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
index 966e957..630a77f 100644 (file)
@@ -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;
        }
 
index e89d098..8b7171c 100644 (file)
@@ -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 <errno.h>
-
 #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;
                        }
index f66b33a..bc92fe3 100644 (file)
@@ -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__ */