+ if (!newbuf) {
+ ret = WIMLIB_ERR_NOMEM;
+ goto out_free_buf;
+ }
+ buf = newbuf;
+ } else {
+ errno = win32_error_to_errno(RtlNtStatusToDosError(status));
+ ERROR_WITH_ERRNO("Failed to read streams of %ls", path);
+ ret = WIMLIB_ERR_READ;
+ goto out_free_buf;
+ }
+ }
+
+ if (io_status.Information == 0) {
+ /* No stream information. */
+ ret = 0;
+ goto out_free_buf;
+ }
+
+ /* Parse one or more stream information structures. */
+ info = (const FILE_STREAM_INFORMATION*)buf;
+ for (;;) {
+ if (info->StreamNameLength <= sizeof(dat.cStreamName) - 2) {
+ dat.StreamSize = info->StreamSize;
+ memcpy(dat.cStreamName, info->StreamName, info->StreamNameLength);
+ dat.cStreamName[info->StreamNameLength / 2] = L'\0';
+
+ /* Capture the stream. */
+ ret = win32_capture_stream(path, path_num_chars, inode,
+ lookup_table, &dat);
+ if (ret)
+ goto out_free_buf;
+ }
+ if (info->NextEntryOffset == 0) {
+ /* No more stream information. */
+ ret = 0;
+ break;
+ }
+ /* Advance to next stream information. */
+ info = (const FILE_STREAM_INFORMATION*)
+ ((const u8*)info + info->NextEntryOffset);
+ }
+out_free_buf:
+ /* Free buffer if allocated on heap. */
+ if (buf != _buf)
+ FREE(buf);
+ return ret;
+
+#else /* WITH_NTDLL */