#include "wimlib/win32_common.h"
#include "wimlib/apply.h"
+#include "wimlib/assert.h"
#include "wimlib/capture.h" /* for mangle_pat() and match_pattern_list() */
#include "wimlib/dentry.h"
#include "wimlib/error.h"
#include "wimlib/lookup_table.h"
#include "wimlib/metadata.h"
+#include "wimlib/paths.h"
#include "wimlib/reparse.h"
#include "wimlib/textfile.h"
#include "wimlib/xml.h"
const struct wim_ads_entry *entry;
NTSTATUS status;
HANDLE h;
+ bool retried;
+ DWORD disposition;
entry = &inode->i_ads_entries[i];
entry->stream_name_nbytes /
sizeof(wchar_t));
path_modified = true;
+
+ retried = false;
+ disposition = FILE_SUPERSEDE;
+ retry:
status = do_create_file(&h, FILE_WRITE_DATA, &allocation_size,
- 0, FILE_SUPERSEDE, 0, ctx);
- if (!NT_SUCCESS(status)) {
+ 0, disposition, 0, ctx);
+ if (unlikely(!NT_SUCCESS(status))) {
+ if (status == STATUS_OBJECT_NAME_NOT_FOUND && !retried) {
+ /* Workaround for defect in the Windows PE
+ * in-memory filesystem implementation:
+ * FILE_SUPERSEDE does not create the file, as
+ * expected and documented, when the named file
+ * does not exist. */
+ retried = true;
+ disposition = FILE_CREATE;
+ goto retry;
+ }
set_errno_from_nt_status(status);
ERROR_WITH_ERRNO("Can't create \"%ls\" "
"(status=0x%08"PRIx32")",
ULONG attrib;
NTSTATUS status;
bool retried = false;
+ DWORD disposition;
inode = dentry->d_inode;
FILE_ATTRIBUTE_ENCRYPTED));
}
build_extraction_path(dentry, ctx);
+ disposition = FILE_SUPERSEDE;
retry:
status = do_create_file(h_ret, GENERIC_READ | GENERIC_WRITE | DELETE,
- NULL, attrib, FILE_SUPERSEDE,
+ NULL, attrib, disposition,
FILE_NON_DIRECTORY_FILE, ctx);
- if (NT_SUCCESS(status)) {
+ if (likely(NT_SUCCESS(status))) {
int ret;
ret = adjust_compression_attribute(*h_ret, dentry, ctx);
return 0;
}
+ if (status == STATUS_OBJECT_NAME_NOT_FOUND && !retried) {
+ /* Workaround for defect in the Windows PE in-memory filesystem
+ * implementation: FILE_SUPERSEDE does not create the file, as
+ * expected and documented, when the named file does not exist.
+ */
+ retried = true;
+ disposition = FILE_CREATE;
+ goto retry;
+ }
+
if (status == STATUS_ACCESS_DENIED && !retried) {
/* We also can't supersede an existing file that has
* FILE_ATTRIBUTE_READONLY set; doing so causes NtCreateFile()