+ DWORD dwDesiredAccess;
+
+ /* Open a handle for NtSetSecurityObject() with as many relevant
+ * access rights as possible.
+ *
+ * We don't know which rights will be actually granted. It
+ * could be less than what is needed to actually assign the full
+ * security descriptor, especially if the process is running as
+ * a non-Administrator. However, by default we just do the best
+ * we can, unless WIMLIB_EXTRACT_FLAG_STRICT_ACLS has been
+ * enabled. The MAXIMUM_ALLOWED access right is seemingly
+ * designed for this use case; however, it does not work
+ * properly in all cases: it can cause CreateFile() to fail with
+ * ERROR_ACCESS_DENIED, even though by definition
+ * MAXIMUM_ALLOWED access only requests access rights that are
+ * *not* denied. (Needless to say, MS does not document this
+ * bug.) */
+
+ dwDesiredAccess = WRITE_DAC |
+ WRITE_OWNER |
+ ACCESS_SYSTEM_SECURITY;
+ for (;;) {
+ DWORD err;
+
+ h = win32_open_existing_file(path, dwDesiredAccess);
+ if (h != INVALID_HANDLE_VALUE)
+ break;
+ err = GetLastError();
+ if (err == ERROR_ACCESS_DENIED ||
+ err == ERROR_PRIVILEGE_NOT_HELD)
+ {
+ /* Don't increment partial_security_descriptors
+ * here or check WIMLIB_EXTRACT_FLAG_STRICT_ACLS
+ * here. It will be done later if needed; here
+ * we are just trying to get as many relevant
+ * access rights as possible. */
+ if (dwDesiredAccess & ACCESS_SYSTEM_SECURITY) {
+ dwDesiredAccess &= ~ACCESS_SYSTEM_SECURITY;
+ continue;
+ }
+ if (dwDesiredAccess & WRITE_DAC) {
+ dwDesiredAccess &= ~WRITE_DAC;
+ continue;
+ }
+ if (dwDesiredAccess & WRITE_OWNER) {
+ dwDesiredAccess &= ~WRITE_OWNER;
+ continue;
+ }
+ }
+ /* Other error, or couldn't open the file even with no
+ * access rights specified. Something else must be
+ * wrong. */
+ set_errno_from_win32_error(err);
+ return WIMLIB_ERR_SET_SECURITY;