Add helper functions for passing paths to progress callbacks
authorEric Biggers <ebiggers3@gmail.com>
Mon, 1 Jun 2015 04:44:09 +0000 (23:44 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Fri, 5 Jun 2015 03:45:35 +0000 (22:45 -0500)
include/wimlib/progress.h
src/capture_common.c
src/progress.c
src/write.c

index b2754445df323a5867bce8f228fccc28b50c2ad0..6d39b7e49804fb0089c8234985aa51e978108a00 100644 (file)
@@ -2,6 +2,7 @@
 #define _WIMLIB_PROGRESS_H
 
 #include "wimlib.h"
+#include "wimlib/paths.h"
 #include "wimlib/types.h"
 
 /* If specified, call the user-provided progress function and check its result.
@@ -55,4 +56,51 @@ set_next_progress(u64 completed_bytes, u64 total_bytes, u64 *next_progress_p)
        }
 }
 
+/* Windows: temporarily remove the stream name from the path  */
+static inline tchar *
+progress_get_streamless_path(const tchar *path)
+{
+       tchar *cookie = NULL;
+#ifdef __WIN32__
+       cookie = (wchar_t *)path_stream_name(path);
+       if (cookie)
+               *--cookie = L'\0'; /* Overwrite the colon  */
+#endif
+       return cookie;
+}
+
+/* Windows: temporarily replace \??\ with \\?\ (to make an NT namespace path
+ * into a Win32 namespace path)  */
+static inline tchar *
+progress_get_win32_path(const tchar *path)
+{
+#ifdef __WIN32__
+       if (!wcsncmp(path, L"\\??\\", 4)) {
+               ((wchar_t *)path)[1] = L'\\';
+               return (wchar_t *)&path[1];
+       }
+#endif
+       return NULL;
+}
+
+/* Windows: restore the NT namespace path  */
+static inline void
+progress_put_win32_path(tchar *cookie)
+{
+#ifdef __WIN32__
+       if (cookie)
+               *cookie = L'?';
+#endif
+}
+
+/* Windows: restore the stream name part of the path  */
+static inline void
+progress_put_streamless_path(tchar *cookie)
+{
+#ifdef __WIN32__
+       if (cookie)
+               *cookie = L':';
+#endif
+}
+
 #endif /* _WIMLIB_PROGRESS_H */
index e088afcbd0cddcc5502bc15045df9a2a00dfb4dc..0fa71adcbd898c5980a85ff42138cc3bef06f3ae 100644 (file)
@@ -285,30 +285,19 @@ try_exclude(const tchar *full_path, const struct capture_params *params)
        }
 
        if (unlikely(params->add_flags & WIMLIB_ADD_FLAG_TEST_FILE_EXCLUSION)) {
+
                union wimlib_progress_info info;
+               tchar *cookie;
 
                info.test_file_exclusion.path = full_path;
                info.test_file_exclusion.will_exclude = false;
 
-       #ifdef __WIN32__
-               /* Hack for Windows...  */
-
-               wchar_t *p_question_mark = NULL;
-
-               if (!wcsncmp(full_path, L"\\??\\", 4)) {
-                       /* Trivial transformation:  NT namespace => Win32 namespace  */
-                       p_question_mark = (wchar_t *)&full_path[1];
-                       *p_question_mark = L'\\';
-               }
-       #endif
+               cookie = progress_get_win32_path(full_path);
 
                ret = call_progress(params->progfunc, WIMLIB_PROGRESS_MSG_TEST_FILE_EXCLUSION,
                                    &info, params->progctx);
 
-       #ifdef __WIN32__
-               if (p_question_mark)
-                       *p_question_mark = L'?';
-       #endif
+               progress_put_win32_path(cookie);
 
                if (ret)
                        return ret;
index cdf014737786df2534ccc1669ad9176198f7fe1b..5696fbae87435284725c154c55dd2f32eb881b88 100644 (file)
@@ -23,8 +23,6 @@
 #  include "config.h"
 #endif
 
-#include <string.h>
-
 #include "wimlib/progress.h"
 
 int
@@ -33,6 +31,7 @@ report_error(wimlib_progress_func_t progfunc,
 {
        int ret;
        union wimlib_progress_info progress;
+       tchar *cookie;
 
        if (error_code == WIMLIB_ERR_SUCCESS ||
            error_code == WIMLIB_ERR_ABORTED_BY_PROGRESS ||
@@ -43,25 +42,12 @@ report_error(wimlib_progress_func_t progfunc,
        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
+       cookie = progress_get_win32_path(path);
 
        ret = call_progress(progfunc, WIMLIB_PROGRESS_MSG_HANDLE_ERROR,
                            &progress, progctx);
 
-#ifdef __WIN32__
-       if (p_question_mark)
-               *p_question_mark = L'?';
-#endif
+       progress_put_win32_path(cookie);
 
        if (ret)
                return ret;
index 47579b549c5a8123f872b5f7bc8b19652e60f5dd..c1d56de3001d1a37d166d22ec6daa9ee6dce163e 100644 (file)
@@ -624,6 +624,8 @@ do_done_with_blob(struct blob_descriptor *blob,
 {
        int ret;
        struct wim_inode *inode;
+       tchar *cookie1;
+       tchar *cookie2;
 
        if (!blob->may_send_done_with_file)
                return 0;
@@ -635,38 +637,14 @@ do_done_with_blob(struct blob_descriptor *blob,
        if (--inode->i_num_remaining_streams > 0)
                return 0;
 
-#ifdef __WIN32__
-       /* XXX: This logic really should be somewhere else.  */
-
-       /* We want the path to the file, but blob->file_on_disk might actually
-        * refer to a named data stream.  Temporarily strip the named data
-        * stream from the path.  */
-       wchar_t *p_colon = NULL;
-       wchar_t *p_question_mark = NULL;
-       const wchar_t *p_stream_name;
-
-       p_stream_name = path_stream_name(blob->file_on_disk);
-       if (unlikely(p_stream_name)) {
-               p_colon = (wchar_t *)(p_stream_name - 1);
-               wimlib_assert(*p_colon == L':');
-               *p_colon = L'\0';
-       }
-
-       /* We also should use a fake Win32 path instead of a NT path  */
-       if (!wcsncmp(blob->file_on_disk, L"\\??\\", 4)) {
-               p_question_mark = &blob->file_on_disk[1];
-               *p_question_mark = L'\\';
-       }
-#endif
+       cookie1 = progress_get_streamless_path(blob->file_on_disk);
+       cookie2 = progress_get_win32_path(blob->file_on_disk);
 
        ret = done_with_file(blob->file_on_disk, progfunc, progctx);
 
-#ifdef __WIN32__
-       if (p_colon)
-               *p_colon = L':';
-       if (p_question_mark)
-               *p_question_mark = L'?';
-#endif
+       progress_put_win32_path(cookie2);
+       progress_put_streamless_path(cookie1);
+
        return ret;
 }