#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.
}
}
+/* 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 */
}
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;
# include "config.h"
#endif
-#include <string.h>
-
#include "wimlib/progress.h"
int
{
int ret;
union wimlib_progress_info progress;
+ tchar *cookie;
if (error_code == WIMLIB_ERR_SUCCESS ||
error_code == WIMLIB_ERR_ABORTED_BY_PROGRESS ||
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;
{
int ret;
struct wim_inode *inode;
+ tchar *cookie1;
+ tchar *cookie2;
if (!blob->may_send_done_with_file)
return 0;
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;
}