]> wimlib.net Git - wimlib/blobdiff - src/win32_apply.c
win32_apply.c: Do not request DELETE access on extraction root
[wimlib] / src / win32_apply.c
index 1737fa1b49d0e9040cfe83f3efe393836240fc44..7148ca814151c1106ee425b1a57b9ce2b4651984 100644 (file)
@@ -831,9 +831,24 @@ win32_extract_stream(const struct wim_dentry *dentry,
        }
 
        DEBUG("Opening \"%ls\"", stream_path);
-       /* DELETE access is needed for SetFileShortNameW(), for some reason. */
-       requestedAccess = GENERIC_READ | GENERIC_WRITE | DELETE |
+       requestedAccess = GENERIC_READ | GENERIC_WRITE |
                          ACCESS_SYSTEM_SECURITY;
+       /* DELETE access is needed for SetFileShortNameW(), for some reason.
+        * But don't request it for the extraction root, for the following
+        * reasons:
+        *
+        * - Requesting DELETE access on the extraction root will cause a
+        *   sharing violation if the extraction root is the current working
+        *   directory (".").
+        * - The extraction root may be extracted to a different name than given
+        *   in the WIM file, in which case the DOS name, if given, would not be
+        *   meaningful.
+        * - For full-image extractions, the root dentry is supposed to be
+        *   unnamed anyway.
+        * - Microsoft's ImageX does not extract the root directory.
+        */
+       if (dentry != args->extract_root)
+               requestedAccess |= DELETE;
 try_open_again:
        /* Open the stream to be extracted.  Depending on what we have set
         * creationDisposition to, we may be creating this for the first time,
@@ -863,7 +878,11 @@ try_open_again:
                        requestedAccess &= ~ACCESS_SYSTEM_SECURITY;
                        goto try_open_again;
                }
-               if (err == ERROR_SHARING_VIOLATION) {
+               if (err == ERROR_SHARING_VIOLATION &&
+                   (inode->i_attributes & (FILE_ATTRIBUTE_ENCRYPTED |
+                                           FILE_ATTRIBUTE_DIRECTORY)) ==
+                       (FILE_ATTRIBUTE_ENCRYPTED | FILE_ATTRIBUTE_DIRECTORY))
+               {
                        if (remaining_sharing_violations) {
                                --remaining_sharing_violations;
                                /* This can happen when restoring encrypted directories
@@ -875,13 +894,12 @@ try_open_again:
                        } else {
                                ERROR("Too many sharing violations; giving up...");
                        }
-               } else {
-                       if (creationDisposition == OPEN_EXISTING)
-                               ERROR("Failed to open \"%ls\"", stream_path);
-                       else
-                               ERROR("Failed to create \"%ls\"", stream_path);
-                       win32_error(err);
                }
+               if (creationDisposition == OPEN_EXISTING)
+                       ERROR("Failed to open \"%ls\"", stream_path);
+               else
+                       ERROR("Failed to create \"%ls\"", stream_path);
+               win32_error(err);
                ret = WIMLIB_ERR_OPEN;
                goto fail;
        }