data = mempcpy(data, rpdata->print_name, rpdata->print_name_nbytes);
*(utf16lechar*)data = cpu_to_le16(0);
data += 2;
- rpbuf_disk->rpdatalen = cpu_to_le16(data - rpbuf - 8);
+ rpbuf_disk->rpdatalen = cpu_to_le16(data - rpbuf - REPARSE_DATA_OFFSET);
*rpbuflen_ret = data - rpbuf;
return 0;
}
} else {
struct wim_inode_stream *strm;
- strm = inode_get_stream(inode, STREAM_TYPE_REPARSE_POINT,
- NO_STREAM_NAME);
+ strm = inode_get_unnamed_stream(inode, STREAM_TYPE_REPARSE_POINT);
if (strm)
blob = stream_blob_resolved(strm);
else
* XXX this could be one of the unknown fields in the WIM dentry. */
rpbuf_disk->rpreserved = cpu_to_le16(0);
- *rpbuflen_ret = rpdatalen + 8;
+ *rpbuflen_ret = rpdatalen + REPARSE_DATA_OFFSET;
return 0;
}
/*
* Get the UNIX-style symlink target from the WIM inode for a reparse point.
* Specifically, this translates the target from UTF-16 to the current multibyte
- * encoding, strips the drive prefix if present, and replaces backslashes with
+ * encoding, strips the drive prefix if present, and swaps backslashes and
* forward slashes.
*
* @inode
}
out_translate_slashes:
- for (size_t i = 0; i < link_target_len; i++)
+ for (size_t i = 0; i < link_target_len; i++) {
if (translated_target[i] == '\\')
translated_target[i] = '/';
+ else if (translated_target[i] == '/')
+ translated_target[i] = '\\';
+ }
out_have_link:
if (link_target_len > bufsize) {
link_target_len = bufsize;
ret = tstr_to_utf16le(target, strlen(target),
&name_utf16le, &name_utf16le_nbytes);
if (ret)
- return ret;
+ goto out;
- for (size_t i = 0; i < name_utf16le_nbytes / 2; i++)
+ for (size_t i = 0; i < name_utf16le_nbytes / 2; i++) {
if (name_utf16le[i] == cpu_to_le16('/'))
name_utf16le[i] = cpu_to_le16('\\');
+ else if (name_utf16le[i] == cpu_to_le16('\\'))
+ name_utf16le[i] = cpu_to_le16('/');
+ }
/* Compatability notes:
*
* is a relative symbolic link. (Quite simple compared to the various
* ways to provide Windows paths.)
*
- * To change a UNIX relative symbolic link to Windows format, we only
- * need to translate it to UTF-16LE and replace forward slashes with
- * backslashes. We do not make any attempt to handle filename character
- * problems, such as a link target that itself contains backslashes on
- * UNIX. Then, for these relative links, we set the reparse header
- * @flags field to SYMBOLIC_LINK_RELATIVE.
+ * To change a UNIX relative symbolic link to Windows format, we need to
+ * translate it to UTF-16LE, swap forward slashes and backslashes, and
+ * set 'rpflags' to SYMBOLIC_LINK_RELATIVE.
*
* For UNIX absolute symbolic links, we must set the @flags field to 0.
* Then, there are multiple options as to actually represent the
}
ret = make_reparse_buffer(&rpdata, (u8*)&rpbuf_disk, &rpbuflen);
- if (ret == 0) {
- if (!inode_add_stream_with_data(inode,
- STREAM_TYPE_REPARSE_POINT,
- NO_STREAM_NAME,
- (u8*)&rpbuf_disk + 8,
- rpbuflen - 8,
- blob_table))
- ret = WIMLIB_ERR_NOMEM;
- }
+ if (ret)
+ goto out_free_name;
+
+ ret = WIMLIB_ERR_NOMEM;
+ if (!inode_add_stream_with_data(inode,
+ STREAM_TYPE_REPARSE_POINT,
+ NO_STREAM_NAME,
+ (u8*)&rpbuf_disk + REPARSE_DATA_OFFSET,
+ rpbuflen - REPARSE_DATA_OFFSET,
+ blob_table))
+ goto out_free_name;
+
+ ret = 0;
+out_free_name:
FREE(name_utf16le);
+out:
return ret;
}