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