@@ -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 ());
@@ -2609,7 +2611,7 @@ int symlink(const char *target, const char *link)
2609
2611
wtarget [len ] = '\\' ;
2610
2612
2611
2613
/* create file symlink */
2612
- if (!CreateSymbolicLinkW (wlink , wtarget , 0 )) {
2614
+ if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags )) {
2613
2615
errno = err_win_to_posix (GetLastError ());
2614
2616
return -1 ;
2615
2617
}
@@ -3131,6 +3133,24 @@ static void maybe_redirect_std_handles(void)
3131
3133
GENERIC_WRITE , FILE_FLAG_NO_BUFFERING );
3132
3134
}
3133
3135
3136
+ static void adjust_symlink_flags (void )
3137
+ {
3138
+ /*
3139
+ * Starting with Windows 10 Build 14972, symbolic links can be created
3140
+ * using CreateSymbolicLink() without elevation by passing the flag
3141
+ * SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE (0x02) as last
3142
+ * parameter, provided the Developer Mode has been enabled. Some
3143
+ * earlier Windows versions complain about this flag with an
3144
+ * ERROR_INVALID_PARAMETER, hence we have to test the build number
3145
+ * specifically.
3146
+ */
3147
+ if (GetVersion () >= 14972 << 16 ) {
3148
+ symlink_file_flags |= 2 ;
3149
+ symlink_directory_flags |= 2 ;
3150
+ }
3151
+
3152
+ }
3153
+
3134
3154
#if defined(_MSC_VER )
3135
3155
3136
3156
#ifdef _DEBUG
@@ -3170,6 +3190,7 @@ int msc_startup(int argc, wchar_t **w_argv, wchar_t **w_env)
3170
3190
#endif
3171
3191
3172
3192
maybe_redirect_std_handles ();
3193
+ adjust_symlink_flags ();
3173
3194
3174
3195
/* determine size of argv conversion buffer */
3175
3196
maxlen = wcslen (_wpgmptr );
@@ -3236,6 +3257,7 @@ void mingw_startup(void)
3236
3257
_startupinfo si ;
3237
3258
3238
3259
maybe_redirect_std_handles ();
3260
+ adjust_symlink_flags ();
3239
3261
3240
3262
/* get wide char arguments and environment */
3241
3263
si .newmode = 0 ;
0 commit comments