+
+/* Set the path at which the directory tree scan is beginning. */
+int
+pathbuf_init(struct scan_params *params, const tchar *root_path)
+{
+ size_t nchars = tstrlen(root_path);
+ size_t alloc_nchars = nchars + 1 + 1024;
+
+ params->cur_path = MALLOC(alloc_nchars * sizeof(tchar));
+ if (!params->cur_path)
+ return WIMLIB_ERR_NOMEM;
+ tmemcpy(params->cur_path, root_path, nchars + 1);
+ params->cur_path_nchars = nchars;
+ params->cur_path_alloc_nchars = alloc_nchars;
+ params->root_path_nchars = nchars;
+ return 0;
+}
+
+/*
+ * Append a filename to the current path.
+ *
+ * If successful, returns a pointer to the filename component and sets
+ * *orig_path_nchars_ret to the old path length, which can be restored later
+ * using pathbuf_truncate(). Otherwise returns NULL (out of memory).
+ */
+const tchar *
+pathbuf_append_name(struct scan_params *params, const tchar *name,
+ size_t name_nchars, size_t *orig_path_nchars_ret)
+{
+ size_t path_nchars = params->cur_path_nchars;
+ size_t required_nchars = path_nchars + 1 + name_nchars + 1;
+ tchar *buf = params->cur_path;
+
+ if (unlikely(required_nchars > params->cur_path_alloc_nchars)) {
+ required_nchars += 1024;
+ buf = REALLOC(buf, required_nchars * sizeof(tchar));
+ if (!buf)
+ return NULL;
+ params->cur_path = buf;
+ params->cur_path_alloc_nchars = required_nchars;
+ }
+ *orig_path_nchars_ret = path_nchars;
+
+ /*
+ * Add the slash, but not if it will be a duplicate (which can happen if
+ * the path to the capture root directory ends in a slash), because
+ * on Windows duplicate slashes sometimes don't work as expected.
+ */
+ if (path_nchars && buf[path_nchars - 1] != OS_PREFERRED_PATH_SEPARATOR)
+ buf[path_nchars++] = OS_PREFERRED_PATH_SEPARATOR;
+
+ tmemcpy(&buf[path_nchars], name, name_nchars);
+ path_nchars += name_nchars;
+ buf[path_nchars] = T('\0');
+ params->cur_path_nchars = path_nchars;
+ return &buf[path_nchars - name_nchars];
+}
+
+/* Truncate the current path to the specified number of characters. */
+void
+pathbuf_truncate(struct scan_params *params, size_t nchars)
+{
+ wimlib_assert(nchars <= params->cur_path_nchars);
+ params->cur_path[nchars] = T('\0');
+ params->cur_path_nchars = nchars;
+}