From: Eric Biggers Date: Wed, 22 Oct 2014 03:17:30 +0000 (-0500) Subject: Add WIMLIB_PROGRESS_MSG_HANDLE_ERROR X-Git-Tag: v1.7.3~15 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=bdea6a2538495fb297e62534f4a6c99b5373fed1 Add WIMLIB_PROGRESS_MSG_HANDLE_ERROR --- diff --git a/Makefile.am b/Makefile.am index c6f8301a..612de3ec 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,6 +59,7 @@ libwim_la_SOURCES = \ src/mount_image.c \ src/pathlist.c \ src/paths.c \ + src/progress.c \ src/resource.c \ src/reference.c \ src/security.c \ diff --git a/include/wimlib.h b/include/wimlib.h index 59e4fb68..ffc9cdbf 100644 --- a/include/wimlib.h +++ b/include/wimlib.h @@ -708,6 +708,25 @@ enum wimlib_progress_msg { * mechanism. */ WIMLIB_PROGRESS_MSG_TEST_FILE_EXCLUSION = 30, + + /** + * An error has occurred and the progress function is being asked + * whether to ignore the error or not. @p info will point to + * ::wimlib_progress_info.handle_error. This is a bidirectional + * message. + * + * This message provides a limited capability for applications to + * recover from "unexpected" errors (i.e. those with no in-library + * handling policy) arising from the underlying operating system. + * Normally, any such error will cause the library to abort the current + * operation. By implementing a handler for this message, the + * application can instead choose to ignore a given error. + * + * Currently, only the following types of errors will result in this + * progress message being sent: + * + */ + WIMLIB_PROGRESS_MSG_HANDLE_ERROR = 31, }; /** Valid return values from user-provided progress functions @@ -1204,6 +1223,24 @@ union wimlib_progress_info { */ bool will_exclude; } test_file_exclusion; + + /** Valid on messages ::WIMLIB_PROGRESS_MSG_HANDLE_ERROR. */ + struct wimlib_progress_info_handle_error { + + /** Path to the file for which the error occurred, or NULL if + * not relevant. */ + const wimlib_tchar *path; + + /** The wimlib error code associated with the error. */ + int error_code; + + /** + * Indicates whether the error will be ignored or not. This + * will be false by default; the progress function may + * set it to true. + */ + bool will_ignore; + } handle_error; }; /** @@ -1724,7 +1761,7 @@ typedef int (*wimlib_iterate_lookup_table_callback_t)(const struct wimlib_resour * Note: This method for file exclusions is independent from the capture * configuration file mechanism. */ -#define WIMLIB_ADD_FLAG_TEST_FILE_EXCLUSION 0x00004000 +#define WIMLIB_ADD_FLAG_TEST_FILE_EXCLUSION 0x00004000 #define WIMLIB_ADD_IMAGE_FLAG_NTFS WIMLIB_ADD_FLAG_NTFS #define WIMLIB_ADD_IMAGE_FLAG_DEREFERENCE WIMLIB_ADD_FLAG_DEREFERENCE diff --git a/include/wimlib/progress.h b/include/wimlib/progress.h index 387afd83..8dbb4c48 100644 --- a/include/wimlib/progress.h +++ b/include/wimlib/progress.h @@ -2,6 +2,7 @@ #define _WIMLIB_PROGRESS_H #include "wimlib.h" +#include "wimlib/types.h" /* If specified, call the user-provided progress function and check its result. */ @@ -28,4 +29,8 @@ call_progress(wimlib_progress_func_t progfunc, return 0; } -#endif +extern int +report_error(wimlib_progress_func_t progfunc, + void *progctx, int error_code, const tchar *path); + +#endif /* _WIMLIB_PROGRESS_H */ diff --git a/src/progress.c b/src/progress.c new file mode 100644 index 00000000..b616dff4 --- /dev/null +++ b/src/progress.c @@ -0,0 +1,71 @@ +/* + * progress.c + */ + +/* + * Copyright (C) 2014 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 + * Software Foundation; either version 3 of the License, or (at your option) any + * later version. + * + * This file is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, see http://www.gnu.org/licenses/. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "wimlib/progress.h" + +int +report_error(wimlib_progress_func_t progfunc, + void *progctx, int error_code, const tchar *path) +{ + int ret; + union wimlib_progress_info progress; + + if (error_code == WIMLIB_ERR_SUCCESS || + error_code == WIMLIB_ERR_ABORTED_BY_PROGRESS || + error_code == WIMLIB_ERR_UNKNOWN_PROGRESS_STATUS) + return error_code; + + progress.handle_error.path = path; + progress.handle_error.error_code = error_code; + progress.handle_error.will_ignore = false; + +#ifdef __WIN32__ + /* Hack for Windows... */ + + wchar_t *p_question_mark = NULL; + + if (!wcsncmp(path, L"\\??\\", 4)) { + /* Trivial transformation: NT namespace => Win32 namespace */ + p_question_mark = (wchar_t *)&path[1]; + *p_question_mark = L'\\'; + } +#endif + + ret = call_progress(progfunc, WIMLIB_PROGRESS_MSG_HANDLE_ERROR, + &progress, progctx); + +#ifdef __WIN32__ + if (p_question_mark) + *p_question_mark = L'?'; +#endif + + if (ret) + return ret; + + if (!progress.handle_error.will_ignore) + return error_code; + + return 0; +}