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