* path.cc (symlink_native): Workaround Windows 8.1 bug: Drop long path

prefix from symlink target path.  Add comment to explain why.
This commit is contained in:
Corinna Vinschen 2013-12-07 10:12:25 +00:00
parent 870f29b5c3
commit 7630387c51
3 changed files with 35 additions and 4 deletions

View File

@ -1,3 +1,8 @@
2013-12-07 Corinna Vinschen <corinna@vinschen.de>
* path.cc (symlink_native): Workaround Windows 8.1 bug: Drop long path
prefix from symlink target path. Add comment to explain why.
2013-12-06 Christopher Faylor <me.cygwin2013@cgf.cx>
* syscalls.cc (dup): Use cygheap_fdnew properly.

View File

@ -1553,7 +1553,6 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
{
win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
final_oldpath = win32_oldpath.get_nt_native_path ();
final_oldpath->Buffer[1] = L'\\';
}
else
{
@ -1591,7 +1590,6 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
{
/* 3a. No valid common path prefix: Create absolute symlink. */
final_oldpath = win32_oldpath.get_nt_native_path ();
final_oldpath->Buffer[1] = L'\\';
}
else
{
@ -1619,15 +1617,34 @@ symlink_native (const char *oldpath, path_conv &win32_newpath)
SetLastError (ERROR_FILE_NOT_FOUND);
return -1;
}
/* Convert native path to DOS UNC path. */
/* Convert native paths to Win32 UNC paths. */
final_newpath = win32_newpath.get_nt_native_path ();
final_newpath->Buffer[1] = L'\\';
/* oldpath may be relative. Make sure to convert only absolute paths
to Win32 paths. */
if (final_oldpath->Buffer[0] == L'\\')
{
/* Workaround Windows 8.1 bug. On Windows 8.1, the ShellExecuteW
function does not handle the long path prefix correctly for symlink
targets. Thus, we create simple short paths < MAX_PATH without
long path prefix. */
if (RtlEqualUnicodePathPrefix (final_oldpath, &ro_u_uncp, TRUE)
&& final_oldpath->Length < (MAX_PATH + 6) * sizeof (WCHAR))
{
final_oldpath->Buffer += 6;
final_oldpath->Buffer[0] = L'\\';
}
else if (final_oldpath->Length < (MAX_PATH + 4) * sizeof (WCHAR))
final_oldpath->Buffer += 4;
else /* Stick to long path, fix native prefix for Win32 API calls. */
final_oldpath->Buffer[1] = L'\\';
}
/* Try to create native symlink. */
if (!CreateSymbolicLinkW (final_newpath->Buffer, final_oldpath->Buffer,
win32_oldpath.isdir ()
? SYMBOLIC_LINK_FLAG_DIRECTORY : 0))
{
/* Repair native path, we still need it. */
/* Repair native newpath, we still need it. */
final_newpath->Buffer[1] = L'?';
return -1;
}

View File

@ -1,3 +1,12 @@
What changed:
-------------
- Don't create native symlinks with target paths having long path prefixes
"\\?\" if the target path is shorter than MAX_PATH characters. This works
around a Windows 8.1 bug: The ShellExecuteW fails if the lpFile parameter
points to a native NTFS symlink with a target path prefixed with "\\?\".
Bug Fixes
---------