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.
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,
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 */
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
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;
}
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\"",
bool wof_running)
{
DWORD bytes_returned;
- DWORD err;
if (wof_running) {
/* The WOF driver is running. We can create the reparse point
*/
/*
- * 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
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;
}
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;
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;
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;
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;
}
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;
}
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;
}
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;
}
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;
}
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));
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;
}
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;
}
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;
}
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;
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;
}
}
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;
}
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;
}
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;
}
&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;
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;
}
}
&& !(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;
}
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;
}
*/
/*
- * 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
# include "config.h"
#endif
-#include <errno.h>
-
#include "wimlib/win32_common.h"
#include "wimlib/assert.h"
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;
}
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;
}
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;
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\"",
}
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:
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;
}
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;
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;
}
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;
}
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;
}
{
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;
}
{
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;
}
}
not_rpfixed = 1;
break;
default:
- ERROR_WITH_ERRNO("\"%ls\": Can't get reparse data",
- printable_path(full_path));
goto out;
}
}
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;
}
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;
}
*/
/*
- * 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
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)
{
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__ */