331
return out;
332
}
333
334
+static DWORD symlink_file_flags = 0, symlink_directory_flags = 1;
335
+
336
enum phantom_symlink_result {
337
PHANTOM_SYMLINK_RETRY,
338
PHANTOM_SYMLINK_DONE,
383
return PHANTOM_SYMLINK_DONE;
384
385
/* otherwise recreate the symlink with directory flag */
384
- if (DeleteFileW(wlink) && CreateSymbolicLinkW(wlink, wtarget, 1))
386
+ if (DeleteFileW(wlink) &&
387
+ CreateSymbolicLinkW(wlink, wtarget, symlink_directory_flags))
388
return PHANTOM_SYMLINK_DIRECTORY;
389
390
errno = err_win_to_posix(GetLastError());
2849
wtarget[len] = '\\';
2850
2851
/* create file symlink */
2849
- if (!CreateSymbolicLinkW(wlink, wtarget, 0)) {
2852
+ if (!CreateSymbolicLinkW(wlink, wtarget, symlink_file_flags)) {
2853
errno = err_win_to_posix(GetLastError());
2854
return -1;
2855
}
3526
GENERIC_WRITE, FILE_FLAG_NO_BUFFERING);
3527
}
3528
3529
+static void adjust_symlink_flags(void)
3530
+{
3531
+ /*
3532
+ * Starting with Windows 10 Build 14972, symbolic links can be created
3533
+ * using CreateSymbolicLink() without elevation by passing the flag
3534
+ * SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE (0x02) as last
3535
+ * parameter, provided the Developer Mode has been enabled. Some
3536
+ * earlier Windows versions complain about this flag with an
3537
+ * ERROR_INVALID_PARAMETER, hence we have to test the build number
3538
+ * specifically.
3539
+ */
3540
+ if (GetVersion() >= 14972 << 16) {
3541
+ symlink_file_flags |= 2;
3542
+ symlink_directory_flags |= 2;
3543
+ }
3544
+
3545
+}
3546
+
3547
#ifdef _MSC_VER
3548
#ifdef _DEBUG
3549
#include <crtdbg.h>
3579
#endif
3580
3581
maybe_redirect_std_handles();
3582
+ adjust_symlink_flags();
3583
3584
/* determine size of argv and environ conversion buffer */
3585
maxlen = wcslen(wargv[0]);