Skip to content

Support creating symlinks outside elevated sessions #1188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 31, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions compat/mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,8 @@ int mingw_core_config(const char *var, const char *value)
return 0;
}

DECLARE_PROC_ADDR(kernel32.dll, BOOL, CreateSymbolicLinkW, LPCWSTR, LPCWSTR, DWORD);
static DWORD symlink_file_flags = 0, symlink_directory_flags = 1;
DECLARE_PROC_ADDR(kernel32.dll, BOOLEAN, CreateSymbolicLinkW, LPCWSTR, LPCWSTR, DWORD);

enum phantom_symlink_result {
PHANTOM_SYMLINK_RETRY,
Expand Down Expand Up @@ -314,7 +315,8 @@ static enum phantom_symlink_result process_phantom_symlink(
return PHANTOM_SYMLINK_DONE;

/* otherwise recreate the symlink with directory flag */
if (DeleteFileW(wlink) && CreateSymbolicLinkW(wlink, wtarget, 1))
if (DeleteFileW(wlink) &&
CreateSymbolicLinkW(wlink, wtarget, symlink_directory_flags))
return PHANTOM_SYMLINK_DIRECTORY;

errno = err_win_to_posix(GetLastError());
Expand Down Expand Up @@ -2656,7 +2658,7 @@ int symlink(const char *target, const char *link)
wtarget[len] = '\\';

/* create file symlink */
if (!CreateSymbolicLinkW(wlink, wtarget, 0)) {
if (!CreateSymbolicLinkW(wlink, wtarget, symlink_file_flags)) {
errno = err_win_to_posix(GetLastError());
return -1;
}
Expand Down Expand Up @@ -3178,6 +3180,24 @@ static void maybe_redirect_std_handles(void)
GENERIC_WRITE, FILE_FLAG_NO_BUFFERING);
}

static void adjust_symlink_flags(void)
{
/*
* Starting with Windows 10 Build 14972, symbolic links can be created
* using CreateSymbolicLink() without elevation by passing the flag
* SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE (0x02) as last
* parameter, provided the Developer Mode has been enabled. Some
* earlier Windows versions complain about this flag with an
* ERROR_INVALID_PARAMETER, hence we have to test the build number
* specifically.
*/
if (GetVersion() >= 14972 << 16) {
symlink_file_flags |= 2;
symlink_directory_flags |= 2;
}

}

#if defined(_MSC_VER)

#ifdef _DEBUG
Expand Down Expand Up @@ -3217,6 +3237,7 @@ int msc_startup(int argc, wchar_t **w_argv, wchar_t **w_env)
#endif

maybe_redirect_std_handles();
adjust_symlink_flags();

/* determine size of argv conversion buffer */
maxlen = wcslen(_wpgmptr);
Expand Down Expand Up @@ -3283,6 +3304,7 @@ void mingw_startup(void)
_startupinfo si;

maybe_redirect_std_handles();
adjust_symlink_flags();

/* get wide char arguments and environment */
si.newmode = 0;
Expand Down