+static int
+win32_set_compressed(HANDLE hFile, const wchar_t *path)
+{
+ USHORT format = COMPRESSION_FORMAT_DEFAULT;
+ DWORD bytesReturned = 0;
+ if (!DeviceIoControl(hFile, FSCTL_SET_COMPRESSION,
+ &format, sizeof(USHORT),
+ NULL, 0,
+ &bytesReturned, NULL))
+ {
+ /* Warning only */
+ DWORD err = GetLastError();
+ WARNING("Failed to set compression flag on \"%ls\"", path);
+ win32_error(err);
+ }
+ return 0;
+}
+
+static int
+win32_set_sparse(HANDLE hFile, const wchar_t *path)
+{
+ DWORD bytesReturned = 0;
+ if (!DeviceIoControl(hFile, FSCTL_SET_SPARSE,
+ NULL, 0,
+ NULL, 0,
+ &bytesReturned, NULL))
+ {
+ /* Warning only */
+ DWORD err = GetLastError();
+ WARNING("Failed to set sparse flag on \"%ls\"", path);
+ win32_error(err);
+ }
+ return 0;
+}
+
+/*
+ * Sets the security descriptor on an extracted file.
+ */
+static int
+win32_set_security_data(const struct wim_inode *inode,
+ const wchar_t *path,
+ struct apply_args *args)
+{
+ PSECURITY_DESCRIPTOR descriptor;
+ unsigned long n;
+ DWORD err;
+
+ descriptor = wim_const_security_data(args->w)->descriptors[inode->i_security_id];
+
+ SECURITY_INFORMATION securityInformation = DACL_SECURITY_INFORMATION |
+ SACL_SECURITY_INFORMATION |
+ OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION;
+again:
+ if (SetFileSecurityW(path, securityInformation, descriptor))
+ return 0;
+ err = GetLastError();
+ if (args->extract_flags & WIMLIB_EXTRACT_FLAG_STRICT_ACLS)
+ goto fail;
+ switch (err) {
+ case ERROR_PRIVILEGE_NOT_HELD:
+ if (securityInformation & SACL_SECURITY_INFORMATION) {
+ n = args->num_set_sacl_priv_notheld++;
+ securityInformation &= ~SACL_SECURITY_INFORMATION;
+ if (n < MAX_SET_SACL_PRIV_NOTHELD_WARNINGS) {
+ WARNING(
+"We don't have enough privileges to set the full security\n"
+" descriptor on \"%ls\"!\n", path);
+ if (args->num_set_sd_access_denied +
+ args->num_set_sacl_priv_notheld == 1)
+ {
+ WARNING("%ls", apply_access_denied_msg);
+ }
+ WARNING("Re-trying with SACL omitted.\n", path);
+ } else if (n == MAX_GET_SACL_PRIV_NOTHELD_WARNINGS) {
+ WARNING(
+"Suppressing further 'privileges not held' error messages when setting\n"
+" security descriptors.");
+ }
+ goto again;
+ }
+ /* Fall through */
+ case ERROR_INVALID_OWNER:
+ case ERROR_ACCESS_DENIED:
+ n = args->num_set_sd_access_denied++;
+ if (n < MAX_SET_SD_ACCESS_DENIED_WARNINGS) {
+ WARNING("Failed to set security descriptor on \"%ls\": "
+ "Access denied!\n", path);
+ if (args->num_set_sd_access_denied +
+ args->num_set_sacl_priv_notheld == 1)
+ {
+ WARNING("%ls", apply_access_denied_msg);
+ }
+ } else if (n == MAX_SET_SD_ACCESS_DENIED_WARNINGS) {
+ WARNING(
+"Suppressing further access denied error messages when setting\n"
+" security descriptors");
+ }
+ return 0;
+ default:
+fail:
+ ERROR("Failed to set security descriptor on \"%ls\"", path);
+ win32_error(err);
+ return WIMLIB_ERR_WRITE;
+ }
+}
+