@@ -270,6 +270,7 @@ int mingw_core_config(const char *var, const char *value)
270
270
return 0 ;
271
271
}
272
272
273
+ static DWORD symlink_file_flags = 0 , symlink_directory_flags = 1 ;
273
274
DECLARE_PROC_ADDR (kernel32 .dll , BOOLEAN , CreateSymbolicLinkW , LPCWSTR , LPCWSTR , DWORD );
274
275
275
276
enum phantom_symlink_result {
@@ -314,7 +315,8 @@ static enum phantom_symlink_result process_phantom_symlink(
314
315
return PHANTOM_SYMLINK_DONE ;
315
316
316
317
/* otherwise recreate the symlink with directory flag */
317
- if (DeleteFileW (wlink ) && CreateSymbolicLinkW (wlink , wtarget , 1 ))
318
+ if (DeleteFileW (wlink ) &&
319
+ CreateSymbolicLinkW (wlink , wtarget , symlink_directory_flags ))
318
320
return PHANTOM_SYMLINK_DIRECTORY ;
319
321
320
322
errno = err_win_to_posix (GetLastError ());
@@ -2656,7 +2658,7 @@ int symlink(const char *target, const char *link)
2656
2658
wtarget [len ] = '\\' ;
2657
2659
2658
2660
/* create file symlink */
2659
- if (!CreateSymbolicLinkW (wlink , wtarget , 0 )) {
2661
+ if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags )) {
2660
2662
errno = err_win_to_posix (GetLastError ());
2661
2663
return -1 ;
2662
2664
}
@@ -3178,6 +3180,24 @@ static void maybe_redirect_std_handles(void)
3178
3180
GENERIC_WRITE , FILE_FLAG_NO_BUFFERING );
3179
3181
}
3180
3182
3183
+ static void adjust_symlink_flags (void )
3184
+ {
3185
+ /*
3186
+ * Starting with Windows 10 Build 14972, symbolic links can be created
3187
+ * using CreateSymbolicLink() without elevation by passing the flag
3188
+ * SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE (0x02) as last
3189
+ * parameter, provided the Developer Mode has been enabled. Some
3190
+ * earlier Windows versions complain about this flag with an
3191
+ * ERROR_INVALID_PARAMETER, hence we have to test the build number
3192
+ * specifically.
3193
+ */
3194
+ if (GetVersion () >= 14972 << 16 ) {
3195
+ symlink_file_flags |= 2 ;
3196
+ symlink_directory_flags |= 2 ;
3197
+ }
3198
+
3199
+ }
3200
+
3181
3201
#if defined(_MSC_VER )
3182
3202
3183
3203
#ifdef _DEBUG
@@ -3217,6 +3237,7 @@ int msc_startup(int argc, wchar_t **w_argv, wchar_t **w_env)
3217
3237
#endif
3218
3238
3219
3239
maybe_redirect_std_handles ();
3240
+ adjust_symlink_flags ();
3220
3241
3221
3242
/* determine size of argv conversion buffer */
3222
3243
maxlen = wcslen (_wpgmptr );
@@ -3283,6 +3304,7 @@ void mingw_startup(void)
3283
3304
_startupinfo si ;
3284
3305
3285
3306
maybe_redirect_std_handles ();
3307
+ adjust_symlink_flags ();
3286
3308
3287
3309
/* get wide char arguments and environment */
3288
3310
si .newmode = 0 ;
0 commit comments