X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fwin32_apply.c;h=d08ea5d83ff090ea91516f5594991770c71e669f;hp=b59f7a8a0b6d795b273150e2cfe0ad3fc70f4da4;hb=c7616d0c686267ff9556f93e0501940bffd0679c;hpb=61db93f82eca3fe9f7676355c709c58cc425a6ad diff --git a/src/win32_apply.c b/src/win32_apply.c index b59f7a8a..d08ea5d8 100644 --- a/src/win32_apply.c +++ b/src/win32_apply.c @@ -44,23 +44,45 @@ win32_start_extract(const wchar_t *path, struct apply_ctx *ctx) if (ret) return ret; - ctx->supported_features.archive_files = 1; - ctx->supported_features.hidden_files = 1; - ctx->supported_features.system_files = 1; - ctx->supported_features.compressed_files = !!(vol_flags & FILE_FILE_COMPRESSION); - ctx->supported_features.encrypted_files = !!(vol_flags & FILE_SUPPORTS_ENCRYPTION); + ctx->supported_features.archive_files = 1; + ctx->supported_features.hidden_files = 1; + ctx->supported_features.system_files = 1; + + if (vol_flags & FILE_FILE_COMPRESSION) + ctx->supported_features.compressed_files = 1; + + if (vol_flags & FILE_SUPPORTS_ENCRYPTION) { + ctx->supported_features.encrypted_files = 1; + ctx->supported_features.encrypted_directories = 1; + } + ctx->supported_features.not_context_indexed_files = 1; - ctx->supported_features.sparse_files = !!(vol_flags & FILE_SUPPORTS_SPARSE_FILES); - ctx->supported_features.named_data_streams = !!(vol_flags & FILE_NAMED_STREAMS); - ctx->supported_features.hard_links = !!(vol_flags & FILE_SUPPORTS_HARD_LINKS); - ctx->supported_features.reparse_points = !!(vol_flags & FILE_SUPPORTS_REPARSE_POINTS); - ctx->supported_features.security_descriptors = !!(vol_flags & FILE_PERSISTENT_ACLS); - ctx->supported_features.short_names = !!supports_SetFileShortName; + + if (vol_flags & FILE_SUPPORTS_SPARSE_FILES) + ctx->supported_features.sparse_files = 1; + + if (vol_flags & FILE_NAMED_STREAMS) + ctx->supported_features.named_data_streams = 1; + + if (vol_flags & FILE_SUPPORTS_HARD_LINKS) + ctx->supported_features.hard_links = 1; + + if (vol_flags & FILE_SUPPORTS_REPARSE_POINTS) { + ctx->supported_features.reparse_points = 1; + if (win32func_CreateSymbolicLinkW) + ctx->supported_features.symlink_reparse_points = 1; + } + + if (vol_flags & FILE_PERSISTENT_ACLS) + ctx->supported_features.security_descriptors = 1; + + if (supports_SetFileShortName) + ctx->supported_features.short_names = 1; return 0; } static int -win32_create_file(const wchar_t *path, struct apply_ctx *ctx) +win32_create_file(const wchar_t *path, struct apply_ctx *ctx, u64 *cookie_ret) { HANDLE h; @@ -77,7 +99,8 @@ error: } static int -win32_create_directory(const wchar_t *path, struct apply_ctx *ctx) +win32_create_directory(const wchar_t *path, struct apply_ctx *ctx, + u64 *cookie_ret) { if (!CreateDirectory(path, NULL)) if (GetLastError() != ERROR_ALREADY_EXISTS) @@ -93,8 +116,33 @@ static int win32_create_hardlink(const wchar_t *oldpath, const wchar_t *newpath, struct apply_ctx *ctx) { - if (!CreateHardLink(newpath, oldpath, NULL)) - goto error; + if (!CreateHardLink(newpath, oldpath, NULL)) { + if (GetLastError() != ERROR_ALREADY_EXISTS) + goto error; + if (!DeleteFile(newpath)) + goto error; + if (!CreateHardLink(newpath, oldpath, NULL)) + goto error; + } + return 0; + +error: + set_errno_from_GetLastError(); + return WIMLIB_ERR_LINK; +} + +static int +win32_create_symlink(const wchar_t *oldpath, const wchar_t *newpath, + struct apply_ctx *ctx) +{ + if (!(*win32func_CreateSymbolicLinkW)(newpath, oldpath, 0)) { + if (GetLastError() != ERROR_ALREADY_EXISTS) + goto error; + if (!DeleteFile(newpath)) + goto error; + if (!(*win32func_CreateSymbolicLinkW)(newpath, oldpath, 0)) + goto error; + } return 0; error: @@ -162,19 +210,19 @@ error: } static int -win32_extract_unnamed_stream(const wchar_t *path, +win32_extract_unnamed_stream(file_spec_t file, struct wim_lookup_table_entry *lte, struct apply_ctx *ctx) { - return win32_extract_stream(path, NULL, 0, lte, ctx); + return win32_extract_stream(file.path, NULL, 0, lte, ctx); } static int -win32_extract_named_stream(const wchar_t *path, const wchar_t *stream_name, +win32_extract_named_stream(file_spec_t file, const wchar_t *stream_name, size_t stream_name_nchars, struct wim_lookup_table_entry *lte, struct apply_ctx *ctx) { - return win32_extract_stream(path, stream_name, + return win32_extract_stream(file.path, stream_name, stream_name_nchars, lte, ctx); } @@ -202,10 +250,11 @@ win32_encrypted_import_cb(unsigned char *data, void *_import_ctx, } static int -win32_extract_encrypted_stream(const wchar_t *path, +win32_extract_encrypted_stream(file_spec_t file, struct wim_lookup_table_entry *lte, struct apply_ctx *ctx) { + const tchar *path = file.path; void *file_ctx; DWORD err; int ret; @@ -342,7 +391,6 @@ win32_set_file_attributes(const wchar_t *path, u32 attributes, goto error; } -success: return 0; error: @@ -422,7 +470,7 @@ error: static int win32_set_security_descriptor(const wchar_t *path, const u8 *desc, size_t desc_size, - struct apply_ctx *ctx, bool strict) + struct apply_ctx *ctx) { SECURITY_INFORMATION info; @@ -432,7 +480,8 @@ win32_set_security_descriptor(const wchar_t *path, const u8 *desc, size_t desc_s SACL_SECURITY_INFORMATION; retry: if (!SetFileSecurity(path, info, (PSECURITY_DESCRIPTOR)desc)) { - if (!strict && GetLastError() == ERROR_PRIVILEGE_NOT_HELD && + if (!(ctx->extract_flags & WIMLIB_EXTRACT_FLAG_STRICT_ACLS) && + GetLastError() == ERROR_PRIVILEGE_NOT_HELD && (info & SACL_SECURITY_INFORMATION)) { info &= ~SACL_SECURITY_INFORMATION; @@ -493,6 +542,7 @@ const struct apply_operations win32_apply_ops = { .create_file = win32_create_file, .create_directory = win32_create_directory, .create_hardlink = win32_create_hardlink, + .create_symlink = win32_create_symlink, .extract_unnamed_stream = win32_extract_unnamed_stream, .extract_named_stream = win32_extract_named_stream, .extract_encrypted_stream = win32_extract_encrypted_stream,