-static bool
-path_is_root_of_drive(const wchar_t *path)
-{
- if (!*path)
- return false;
-
- if (*path != L'/' && *path != L'\\') {
- if (*(path + 1) == L':')
- path += 2;
- else
- return false;
- }
- while (*path == L'/' || *path == L'\\')
- path++;
- return (*path == L'\0');
-}
-
-static inline DWORD
-win32_mask_attributes(DWORD i_attributes)
-{
- return i_attributes & ~(FILE_ATTRIBUTE_SPARSE_FILE |
- FILE_ATTRIBUTE_COMPRESSED |
- FILE_ATTRIBUTE_REPARSE_POINT |
- FILE_ATTRIBUTE_DIRECTORY |
- FILE_ATTRIBUTE_ENCRYPTED |
- FILE_FLAG_DELETE_ON_CLOSE |
- FILE_FLAG_NO_BUFFERING |
- FILE_FLAG_OPEN_NO_RECALL |
- FILE_FLAG_OVERLAPPED |
- FILE_FLAG_RANDOM_ACCESS |
- /*FILE_FLAG_SESSION_AWARE |*/
- FILE_FLAG_SEQUENTIAL_SCAN |
- FILE_FLAG_WRITE_THROUGH);
-}
-
-static inline DWORD
-win32_get_create_flags_and_attributes(DWORD i_attributes)
-{
- /*
- * Some attributes cannot be set by passing them to CreateFile(). In
- * particular:
- *
- * FILE_ATTRIBUTE_DIRECTORY:
- * CreateDirectory() must be called instead of CreateFile().
- *
- * FILE_ATTRIBUTE_SPARSE_FILE:
- * Needs an ioctl.
- * See: win32_set_sparse().
- *
- * FILE_ATTRIBUTE_COMPRESSED:
- * Not clear from the documentation, but apparently this needs an
- * ioctl as well.
- * See: win32_set_compressed().
- *
- * FILE_ATTRIBUTE_REPARSE_POINT:
- * Needs an ioctl, with the reparse data specified.
- * See: win32_set_reparse_data().
- *
- * In addition, clear any file flags in the attributes that we don't
- * want, but also specify FILE_FLAG_OPEN_REPARSE_POINT and
- * FILE_FLAG_BACKUP_SEMANTICS as we are a backup application.
- */
- return win32_mask_attributes(i_attributes) |
- FILE_FLAG_OPEN_REPARSE_POINT |
- FILE_FLAG_BACKUP_SEMANTICS;
-}
-
-/* Set compression and/or sparse attributes on a stream, if supported by the
- * volume. */
-static int
-win32_set_special_stream_attributes(HANDLE hFile, const struct wim_inode *inode,
- struct wim_lookup_table_entry *unnamed_stream_lte,
- const wchar_t *path, unsigned vol_flags)
-{
- int ret;
-
- if (inode->i_attributes & FILE_ATTRIBUTE_COMPRESSED) {
- if (vol_flags & FILE_FILE_COMPRESSION) {
- ret = win32_set_compression_state(hFile,
- COMPRESSION_FORMAT_DEFAULT,
- path);
- if (ret)
- return ret;
- } else {
- DEBUG("Cannot set compression attribute on \"%ls\": "
- "volume does not support transparent compression",
- path);
- }
- }
-
- if (inode->i_attributes & FILE_ATTRIBUTE_SPARSE_FILE) {
- if (vol_flags & FILE_SUPPORTS_SPARSE_FILES) {
- DEBUG("Setting sparse flag on \"%ls\"", path);
- ret = win32_set_sparse(hFile, path);
- if (ret)
- return ret;
- } else {
- DEBUG("Cannot set sparse attribute on \"%ls\": "
- "volume does not support sparse files",
- path);
- }
- }
- return 0;
-}
-
-/* Pre-create directories; extract encrypted streams */
-static int
-win32_begin_extract_unnamed_stream(const struct wim_inode *inode,
- const struct wim_lookup_table_entry *lte,
- const wchar_t *path,
- DWORD *creationDisposition_ret,
- unsigned int vol_flags)