]> wimlib.net Git - wimlib/blobdiff - src/win32_apply.c
win32_apply.c: add message about known issue with WindowsApps directory
[wimlib] / src / win32_apply.c
index 4c2f97d34d41ff3ad5e9bbdb37618e4a4ef01d4d..395e69841820a08da85f4645be4c47cf5f544abe 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 /*
- * 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
@@ -267,9 +267,10 @@ win32_get_supported_features(const wchar_t *target,
 
        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;
@@ -1647,8 +1648,24 @@ retry:
                                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;
        }
 
@@ -1675,15 +1692,18 @@ retry:
                 * 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)) {
@@ -2105,6 +2125,26 @@ try_rpfix(struct reparse_buffer_disk *rpbuf, u16 *rpbuflen_p,
 
        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];