@@ -271,6 +271,7 @@ int mingw_core_config(const char *var, const char *value, void *cb)
271
271
return 0 ;
272
272
}
273
273
274
+ static DWORD symlink_file_flags = 0 , symlink_directory_flags = 1 ;
274
275
DECLARE_PROC_ADDR (kernel32 .dll , BOOLEAN , CreateSymbolicLinkW , LPCWSTR , LPCWSTR , DWORD );
275
276
276
277
enum phantom_symlink_result {
@@ -315,7 +316,8 @@ static enum phantom_symlink_result process_phantom_symlink(
315
316
return PHANTOM_SYMLINK_DONE ;
316
317
317
318
/* otherwise recreate the symlink with directory flag */
318
- if (DeleteFileW (wlink ) && CreateSymbolicLinkW (wlink , wtarget , 1 ))
319
+ if (DeleteFileW (wlink ) &&
320
+ CreateSymbolicLinkW (wlink , wtarget , symlink_directory_flags ))
319
321
return PHANTOM_SYMLINK_DIRECTORY ;
320
322
321
323
errno = err_win_to_posix (GetLastError ());
@@ -2578,7 +2580,7 @@ int symlink(const char *target, const char *link)
2578
2580
wtarget [len ] = '\\' ;
2579
2581
2580
2582
/* create file symlink */
2581
- if (!CreateSymbolicLinkW (wlink , wtarget , 0 )) {
2583
+ if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags )) {
2582
2584
errno = err_win_to_posix (GetLastError ());
2583
2585
return -1 ;
2584
2586
}
@@ -3100,6 +3102,24 @@ static void maybe_redirect_std_handles(void)
3100
3102
GENERIC_WRITE , FILE_FLAG_NO_BUFFERING );
3101
3103
}
3102
3104
3105
+ static void adjust_symlink_flags (void )
3106
+ {
3107
+ /*
3108
+ * Starting with Windows 10 Build 14972, symbolic links can be created
3109
+ * using CreateSymbolicLink() without elevation by passing the flag
3110
+ * SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE (0x02) as last
3111
+ * parameter, provided the Developer Mode has been enabled. Some
3112
+ * earlier Windows versions complain about this flag with an
3113
+ * ERROR_INVALID_PARAMETER, hence we have to test the build number
3114
+ * specifically.
3115
+ */
3116
+ if (GetVersion () >= 14972 << 16 ) {
3117
+ symlink_file_flags |= 2 ;
3118
+ symlink_directory_flags |= 2 ;
3119
+ }
3120
+
3121
+ }
3122
+
3103
3123
#if defined(_MSC_VER )
3104
3124
3105
3125
#ifdef _DEBUG
@@ -3139,6 +3159,7 @@ int msc_startup(int argc, wchar_t **w_argv, wchar_t **w_env)
3139
3159
#endif
3140
3160
3141
3161
maybe_redirect_std_handles ();
3162
+ adjust_symlink_flags ();
3142
3163
3143
3164
/* determine size of argv conversion buffer */
3144
3165
maxlen = wcslen (_wpgmptr );
@@ -3205,6 +3226,7 @@ void mingw_startup(void)
3205
3226
_startupinfo si ;
3206
3227
3207
3228
maybe_redirect_std_handles ();
3229
+ adjust_symlink_flags ();
3208
3230
3209
3231
/* get wide char arguments and environment */
3210
3232
si .newmode = 0 ;
0 commit comments