win32_apply.c: Use volume handle when enabling short names
authorEric Biggers <ebiggers3@gmail.com>
Sun, 17 Aug 2014 21:58:18 +0000 (16:58 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Sun, 17 Aug 2014 22:02:32 +0000 (17:02 -0500)
Otherwise it doesn't work.

include/wimlib/win32_common.h
src/wimboot.c
src/win32_apply.c
src/win32_common.c

index 7cd991e..e5317b6 100644 (file)
@@ -157,4 +157,7 @@ typedef struct _FILE_FS_PERSISTENT_VOLUME_INFORMATION {
 extern int
 win32_path_to_nt_path(const wchar_t *win32_path, UNICODE_STRING *nt_path);
 
+extern int
+win32_get_drive_path(const wchar_t *file_path, wchar_t drive_path[7]);
+
 #endif /* _WIMLIB_WIN32_COMMON_H */
index 35fe13a..514ff8c 100644 (file)
@@ -831,26 +831,6 @@ out:
        return ret;
 }
 
-static int
-win32_get_drive_path(const wchar_t *file_path, wchar_t drive_path[7])
-{
-       tchar *file_abspath;
-
-       file_abspath = realpath(file_path, NULL);
-       if (!file_abspath)
-               return WIMLIB_ERR_NOMEM;
-
-       if (file_abspath[0] == L'\0' || file_abspath[1] != L':') {
-               ERROR("\"%ls\": Path format not recognized", file_abspath);
-               FREE(file_abspath);
-               return WIMLIB_ERR_UNSUPPORTED;
-       }
-
-       wsprintf(drive_path, L"\\\\.\\%lc:", file_abspath[0]);
-       FREE(file_abspath);
-       return 0;
-}
-
 /* Try to attach an instance of the Windows Overlay File System Filter Driver to
  * the specified drive (such as C:)  */
 static bool
index 89ecd21..1f68b69 100644 (file)
@@ -799,27 +799,38 @@ maybe_clear_encryption_attribute(HANDLE *h_ptr, const struct wim_dentry *dentry,
 /* Try to enable short name support on the target volume.  If successful, return
  * true.  If unsuccessful, issue a warning and return false.  */
 static bool
-try_to_enable_short_names(struct win32_apply_ctx *ctx)
+try_to_enable_short_names(const wchar_t *volume)
 {
+       HANDLE h;
        FILE_FS_PERSISTENT_VOLUME_INFORMATION info;
-       NTSTATUS status;
+       BOOL bret;
+       DWORD bytesReturned;
+
+       h = CreateFile(volume, GENERIC_WRITE,
+                      FILE_SHARE_VALID_FLAGS, NULL, OPEN_EXISTING,
+                      FILE_FLAG_BACKUP_SEMANTICS, NULL);
+       if (h == INVALID_HANDLE_VALUE)
+               goto fail;
 
        info.VolumeFlags = 0;
        info.FlagMask = PERSISTENT_VOLUME_STATE_SHORT_NAME_CREATION_DISABLED;
        info.Version = 1;
        info.Reserved = 0;
 
-       status = (*func_NtFsControlFile)(ctx->h_target, NULL, NULL, NULL,
-                                        &ctx->iosb,
-                                        FSCTL_SET_PERSISTENT_VOLUME_STATE,
-                                        &info, sizeof(info), NULL, 0);
-       if (!NT_SUCCESS(status)) {
-               WARNING("Failed to enable short name support on target volume "
-                       "(status=0x%08"PRIx32")", (u32)status);
-               return false;
-       }
+       bret = DeviceIoControl(h, FSCTL_SET_PERSISTENT_VOLUME_STATE,
+                              &info, sizeof(info), NULL, 0,
+                              &bytesReturned, NULL);
 
+       CloseHandle(h);
+
+       if (!bret)
+               goto fail;
        return true;
+
+fail:
+       WARNING("Failed to enable short name support on %ls "
+               "(err=%"PRIu32")", volume + 4, (u32)GetLastError());
+       return false;
 }
 
 /* Set the short name on the open file @h which has been created at the location
@@ -860,8 +871,16 @@ retry:
                if (dentry->short_name_nbytes == 0)
                        return 0;
                if (!ctx->tried_to_enable_short_names) {
+                       wchar_t volume[7];
+                       int ret;
+
                        ctx->tried_to_enable_short_names = true;
-                       if (try_to_enable_short_names(ctx))
+
+                       ret = win32_get_drive_path(ctx->common.target,
+                                                  volume);
+                       if (ret)
+                               return ret;
+                       if (try_to_enable_short_names(volume))
                                goto retry;
                }
        }
index 48e2146..d380e82 100644 (file)
@@ -645,4 +645,25 @@ win32_path_to_nt_path(const wchar_t *win32_path, UNICODE_STRING *nt_path)
        return WIMLIB_ERR_INVALID_PARAM;
 }
 
+int
+win32_get_drive_path(const wchar_t *file_path, wchar_t drive_path[7])
+{
+       tchar *file_abspath;
+
+       file_abspath = realpath(file_path, NULL);
+       if (!file_abspath)
+               return WIMLIB_ERR_NOMEM;
+
+       if (file_abspath[0] == L'\0' || file_abspath[1] != L':') {
+               ERROR("\"%ls\": Path format not recognized", file_abspath);
+               FREE(file_abspath);
+               return WIMLIB_ERR_UNSUPPORTED;
+       }
+
+       wsprintf(drive_path, L"\\\\.\\%lc:", file_abspath[0]);
+       FREE(file_abspath);
+       return 0;
+}
+
+
 #endif /* __WIN32__ */