+static void
+set_prepopulate_pats(struct apply_ctx *ctx, struct string_set *s)
+{
+ ctx->private[2] = (intptr_t)s;
+}
+
+static struct string_set *
+alloc_prepopulate_pats(struct apply_ctx *ctx)
+{
+ struct string_set *s = CALLOC(1, sizeof(*s));
+ set_prepopulate_pats(ctx, s);
+ return s;
+}
+
+static struct string_set *
+get_prepopulate_pats(struct apply_ctx *ctx)
+{
+ return (struct string_set *)(ctx->private[2]);
+}
+
+static void
+free_prepopulate_pats(struct apply_ctx *ctx)
+{
+ struct string_set *s;
+
+ s = get_prepopulate_pats(ctx);
+ if (s) {
+ FREE(s->strings);
+ FREE(s);
+ }
+ set_prepopulate_pats(ctx, NULL);
+
+ FREE((void *)ctx->private[3]);
+ ctx->private[3] = (intptr_t)NULL;
+}
+
+static int
+load_prepopulate_pats(struct apply_ctx *ctx)
+{
+ int ret;
+ struct wim_dentry *dentry;
+ struct wim_lookup_table_entry *lte;
+ struct string_set *s;
+ const tchar *path = WIMLIB_WIM_PATH_SEPARATOR_STRING T("Windows")
+ WIMLIB_WIM_PATH_SEPARATOR_STRING T("System32")
+ WIMLIB_WIM_PATH_SEPARATOR_STRING T("WimBootCompress.ini");
+ void *buf;
+ void *mem;
+ struct text_file_section sec;
+
+ dentry = get_dentry(ctx->wim, path, WIMLIB_CASE_INSENSITIVE);
+ if (!dentry ||
+ (dentry->d_inode->i_attributes & (FILE_ATTRIBUTE_DIRECTORY |
+ FILE_ATTRIBUTE_REPARSE_POINT |
+ FILE_ATTRIBUTE_ENCRYPTED)) ||
+ !(lte = inode_unnamed_lte(dentry->d_inode, ctx->wim->lookup_table)))
+ {
+ WARNING("%"TS" does not exist in WIM image!", path);
+ return WIMLIB_ERR_PATH_DOES_NOT_EXIST;
+ }
+
+ ret = read_full_stream_into_alloc_buf(lte, &buf);
+ if (ret)
+ return ret;
+
+ s = alloc_prepopulate_pats(ctx);
+ if (!s) {
+ FREE(buf);
+ return WIMLIB_ERR_NOMEM;
+ }
+
+ sec.name = T("PrepopulateList");
+ sec.strings = s;
+
+ ret = do_load_text_file(path, buf, lte->size, &mem, &sec, 1,
+ LOAD_TEXT_FILE_REMOVE_QUOTES |
+ LOAD_TEXT_FILE_NO_WARNINGS,
+ mangle_pat);
+ FREE(buf);
+ if (ret) {
+ free_prepopulate_pats(ctx);
+ return ret;
+ }
+ ctx->private[3] = (intptr_t)mem;
+ return 0;
+}
+
+static bool
+in_prepopulate_list(struct wim_dentry *dentry,
+ struct apply_ctx *ctx)
+{
+ struct string_set *pats;
+ const tchar *path;
+
+ pats = get_prepopulate_pats(ctx);
+ if (!pats)
+ return false;
+ path = dentry_full_path(dentry);
+ if (!path)
+ return false;
+
+ return match_pattern(path, path_basename(path), pats);
+}
+