@@ -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 {
@@ -358,7 +359,8 @@ process_phantom_symlink(const wchar_t *wtarget, const wchar_t *wlink)
358
359
return PHANTOM_SYMLINK_DONE ;
359
360
360
361
/* otherwise recreate the symlink with directory flag */
361
- if (DeleteFileW (wlink ) && CreateSymbolicLinkW (wlink , wtarget , 1 ))
362
+ if (DeleteFileW (wlink ) &&
363
+ CreateSymbolicLinkW (wlink , wtarget , symlink_directory_flags ))
362
364
return PHANTOM_SYMLINK_DIRECTORY ;
363
365
364
366
errno = err_win_to_posix (GetLastError ());
@@ -2576,7 +2578,7 @@ int symlink(const char *target, const char *link)
2576
2578
wtarget [len ] = '\\' ;
2577
2579
2578
2580
/* create file symlink */
2579
- if (!CreateSymbolicLinkW (wlink , wtarget , 0 )) {
2581
+ if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags )) {
2580
2582
errno = err_win_to_posix (GetLastError ());
2581
2583
return -1 ;
2582
2584
}
@@ -3098,6 +3100,24 @@ static void maybe_redirect_std_handles(void)
3098
3100
GENERIC_WRITE , FILE_FLAG_NO_BUFFERING );
3099
3101
}
3100
3102
3103
+ static void adjust_symlink_flags (void )
3104
+ {
3105
+ /*
3106
+ * Starting with Windows 10 Build 14972, symbolic links can be created
3107
+ * using CreateSymbolicLink() without elevation by passing the flag
3108
+ * SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE (0x02) as last
3109
+ * parameter, provided the Developer Mode has been enabled. Some
3110
+ * earlier Windows versions complain about this flag with an
3111
+ * ERROR_INVALID_PARAMETER, hence we have to test the build number
3112
+ * specifically.
3113
+ */
3114
+ if (GetVersion () >= 14972 << 16 ) {
3115
+ symlink_file_flags |= 2 ;
3116
+ symlink_directory_flags |= 2 ;
3117
+ }
3118
+
3119
+ }
3120
+
3101
3121
#if defined(_MSC_VER )
3102
3122
3103
3123
#ifdef _DEBUG
@@ -3137,6 +3157,7 @@ int msc_startup(int argc, wchar_t **w_argv, wchar_t **w_env)
3137
3157
#endif
3138
3158
3139
3159
maybe_redirect_std_handles ();
3160
+ adjust_symlink_flags ();
3140
3161
3141
3162
/* determine size of argv conversion buffer */
3142
3163
maxlen = wcslen (_wpgmptr );
@@ -3203,6 +3224,7 @@ void mingw_startup(void)
3203
3224
_startupinfo si ;
3204
3225
3205
3226
maybe_redirect_std_handles ();
3227
+ adjust_symlink_flags ();
3206
3228
3207
3229
/* get wide char arguments and environment */
3208
3230
si .newmode = 0 ;
0 commit comments