-/* Extract a file, directory, reparse point, or hard link to an
- * already-extracted file using the Win32 API */
-int
-win32_do_apply_dentry(const wchar_t *output_path,
- size_t output_path_num_chars,
- struct wim_dentry *dentry,
- struct apply_args *args)
-{
- int ret;
- struct wim_inode *inode = dentry->d_inode;
-
- ret = win32_check_vol_flags(output_path, dentry, args);
- if (ret)
- return ret;
- if (inode->i_nlink > 1 && inode->i_extracted_file != NULL) {
- /* Linked file, with another name already extracted. Create a
- * hard link. */
- ret = win32_try_hard_link(output_path, inode, args);
- if (ret >= 0)
- return ret;
- /* Negative return value from win32_try_hard_link() indicates
- * that hard links are probably not supported by the volume.
- * Fall back to extracting a copy of the file. */
- }
-
- /* If this is a reparse point and the volume does not support reparse
- * points, just skip it completely. */
- if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT &&
- !(args->vol_flags & FILE_SUPPORTS_REPARSE_POINTS))
- {
- WARNING("Not extracting reparse point \"%ls\"", output_path);
- } else {
- /* Create the file, directory, or reparse point, and extract the
- * data streams. */
- ret = win32_extract_streams(dentry, output_path, args);
- if (ret)
- return ret;
- }
- if (inode->i_extracted_file == NULL) {
- const struct wim_lookup_table_entry *lte;
-
- /* Tally bytes extracted, including all alternate data streams,
- * unless we extracted a hard link (or, at least extracted a
- * name that was supposed to be a hard link) */
- for (unsigned i = 0; i <= inode->i_num_ads; i++) {
- lte = inode_stream_lte_resolved(inode, i);
- if (lte)
- args->progress.extract.completed_bytes +=
- wim_resource_size(lte);
- }
- if (inode->i_nlink > 1) {
- /* Save extracted path for a later call to
- * CreateHardLinkW() if this inode has multiple links.
- * */
- inode->i_extracted_file = WSTRDUP(output_path);
- if (!inode->i_extracted_file)
- return WIMLIB_ERR_NOMEM;
+ for (;;) {
+ err = do_win32_set_security_descriptor(h, path, info,
+ (PSECURITY_DESCRIPTOR)desc);
+ if (err == ERROR_SUCCESS)
+ break;
+ if ((err == ERROR_PRIVILEGE_NOT_HELD ||
+ err == ERROR_ACCESS_DENIED) &&
+ !(ctx->extract_flags & WIMLIB_EXTRACT_FLAG_STRICT_ACLS))
+ {
+ if (info & SACL_SECURITY_INFORMATION) {
+ info &= ~SACL_SECURITY_INFORMATION;
+ ctx->partial_security_descriptors++;
+ continue;
+ }
+ if (info & DACL_SECURITY_INFORMATION) {
+ info &= ~DACL_SECURITY_INFORMATION;
+ continue;
+ }
+ if (info & OWNER_SECURITY_INFORMATION) {
+ info &= ~OWNER_SECURITY_INFORMATION;
+ continue;
+ }
+ ctx->partial_security_descriptors--;
+ ctx->no_security_descriptors++;
+ break;