*/
/*
- * Copyright (C) 2013, 2014, 2015 Eric Biggers
+ * Copyright (C) 2013-2016 Eric Biggers
*
* This file is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
get_vol_flags(target, &vol_flags, &short_names_supported);
- supported_features->archive_files = 1;
+ supported_features->readonly_files = 1;
supported_features->hidden_files = 1;
supported_features->system_files = 1;
+ supported_features->archive_files = 1;
if (vol_flags & FILE_FILE_COMPRESSION)
supported_features->compressed_files = 1;
goto retry;
}
}
- winnt_error(status, L"Can't create directory \"%ls\"",
- current_path(ctx));
+ const wchar_t *path = current_path(ctx);
+ winnt_error(status, L"Can't create directory \"%ls\"", path);
+
+ /* Check for known issue with WindowsApps directory. */
+ if (status == STATUS_ACCESS_DENIED &&
+ (wcsstr(path, L"\\WindowsApps\\") ||
+ wcsstr(path, L"\\InfusedApps\\"))) {
+ ERROR(
+"You seem to be trying to extract files to the WindowsApps directory.\n"
+" Windows 8.1 and later use new file permissions in this directory that\n"
+" cannot be overridden, even by backup/restore programs. To extract your\n"
+" files anyway, you need to choose a different target directory, delete\n"
+" the WindowsApps directory entirely, reformat the volume, do the\n"
+" extraction from a non-broken operating system such as Windows 7 or\n"
+" Linux, or wait for Microsoft to fix the design flaw in their operating\n"
+" system. This is *not* a bug in wimlib. See this thread for more\n"
+" information: https://wimlib.net/forums/viewtopic.php?f=1&t=261");
+ }
return WIMLIB_ERR_MKDIR;
}
* STATUS_ACCESS_DENIED when creating a named data stream that
* was just deleted, using a directory-relative open. I have no
* idea why Windows is broken in this case. */
- static const SECURITY_DESCRIPTOR_RELATIVE desc = {
- .Revision = SECURITY_DESCRIPTOR_REVISION1,
- .Control = SE_SELF_RELATIVE | SE_DACL_PRESENT,
- .Owner = 0,
- .Group = 0,
- .Sacl = 0,
- .Dacl = 0,
- };
- (*func_NtSetSecurityObject)(h, DACL_SECURITY_INFORMATION, (void *)&desc);
+ if (!(ctx->common.extract_flags & WIMLIB_EXTRACT_FLAG_NO_ACLS)) {
+ static const SECURITY_DESCRIPTOR_RELATIVE desc = {
+ .Revision = SECURITY_DESCRIPTOR_REVISION1,
+ .Control = SE_SELF_RELATIVE | SE_DACL_PRESENT,
+ .Owner = 0,
+ .Group = 0,
+ .Sacl = 0,
+ .Dacl = 0,
+ };
+ (*func_NtSetSecurityObject)(h, DACL_SECURITY_INFORMATION,
+ (void *)&desc);
+ }
}
if (!dentry_is_root(dentry)) {
target_ntpath_nchars = ctx->target_ntpath.Length / sizeof(wchar_t);
+ /* If the target directory is a filesystem root, such as \??\C:\, then
+ * it already will have a trailing slash. Don't include this slash if
+ * we are already adding slashes via 'relpath'. This prevents an extra
+ * slash from being generated each time the link is extracted. And
+ * unlike on UNIX, the number of slashes in paths on Windows can be
+ * significant; Windows won't understand the link target if it contains
+ * too many slashes. */
+ if (target_ntpath_nchars > 0 && relpath_nchars > 0 &&
+ ctx->target_ntpath.Buffer[target_ntpath_nchars - 1] == L'\\')
+ target_ntpath_nchars--;
+
+ /* Also remove extra slashes from the beginning of 'relpath'. Normally
+ * this isn't needed, but this is here to make the extra slash(es) added
+ * by wimlib pre-v1.9.1 get removed automatically. */
+ while (relpath_nchars >= 2 &&
+ relpath[0] == L'\\' && relpath[1] == L'\\') {
+ relpath++;
+ relpath_nchars--;
+ }
+
fixed_subst_name_nchars = target_ntpath_nchars + relpath_nchars;
wchar_t fixed_subst_name[fixed_subst_name_nchars];