- for (size_t i = 0; i < name_utf16le_nbytes / 2; i++)
- if (name_utf16le[i] == cpu_to_le16('/'))
- name_utf16le[i] = cpu_to_le16('\\');
-
- /* Compatability notes:
- *
- * On UNIX, an absolute symbolic link begins with '/'; everything else
- * 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 backslashes with forward
- * slashes. 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.
- *
- * For UNIX absolute symbolic links, we must set the @flags field to 0.
- * Then, there are multiple options as to actually represent the
- * absolute link targets:
- *
- * (1) An absolute path beginning with one backslash character. similar
- * to UNIX-style, just with a different path separator. Print name same
- * as substitute name.
- *
- * (2) Absolute path beginning with drive letter followed by a
- * backslash. Print name same as substitute name.
- *
- * (3) Absolute path beginning with drive letter followed by a
- * backslash; substitute name prefixed with \??\, otherwise same as
- * print name.
- *
- * We choose option (3) here, and we just assume C: for the drive
- * letter. The reasoning for this is:
- *
- * (1) Microsoft imagex.exe has a bug where it does not attempt to do
- * reparse point fixups for these links, even though they are valid
- * absolute links. (Note: in this case prefixing the substitute name
- * with \??\ does not work; it just makes the data unable to be restored
- * at all.)
- * (2) Microsoft imagex.exe will fail when doing reparse point fixups
- * for these. It apparently contains a bug that causes it to create an
- * invalid reparse point, which then cannot be restored.
- * (3) This is the only option I tested for which reparse point fixups
- * worked properly in Microsoft imagex.exe.
- *
- * So option (3) it is.
- */
+ /* Translate forward slashes (UNIX path separator) to backslashes
+ * (Windows NT path separator). In addition, translate backslashes to
+ * forward slashes; this enables lossless handling of UNIX symbolic link
+ * targets that contain the backslash character. */
+ for (utf16lechar *p = target; *p; p++) {
+ if (*p == cpu_to_le16('/'))
+ *p = cpu_to_le16('\\');
+ else if (*p == cpu_to_le16('\\'))
+ *p = cpu_to_le16('/');
+ }