diff options
author | Ron Yorston <rmy@pobox.com> | 2021-02-12 14:11:01 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2021-02-12 14:11:01 +0000 |
commit | 7587b56c10a4d11fe434e3eaa51212113f09ec10 (patch) | |
tree | 219264f8c4079d13ab8c29d9d90f04b22e6470bc /win32/mingw.c | |
parent | 1b61a02b5139a47e2e3ac8be5afca325d7b3cea7 (diff) | |
download | busybox-w32-7587b56c10a4d11fe434e3eaa51212113f09ec10.tar.gz busybox-w32-7587b56c10a4d11fe434e3eaa51212113f09ec10.tar.bz2 busybox-w32-7587b56c10a4d11fe434e3eaa51212113f09ec10.zip |
win32: implement symlink(2)
Provide an implementation of symlink(2).
Calls to symlink(2) will fail in default Windows installations unless
running with elevated privileges. Failure to create a symlink when
extracting files from an archive is therefore treated as a non-fatal
error.
There are two ways to permit the creation of symlinks:
- Edit security policy to give users the 'Create symbolic links'
privilege. Unfortunately this doesn't work for users who are an
Administrator.
- Enable developer mode, which is available in later versions of
Windows 10.
The ability to create symlinks is not available in Windows XP
or ReactOS.
Diffstat (limited to 'win32/mingw.c')
-rw-r--r-- | win32/mingw.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/win32/mingw.c b/win32/mingw.c index 41dba9857..a6362333d 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -1063,6 +1063,41 @@ int link(const char *oldpath, const char *newpath) | |||
1063 | return 0; | 1063 | return 0; |
1064 | } | 1064 | } |
1065 | 1065 | ||
1066 | #ifndef SYMBOLIC_LINK_FLAG_DIRECTORY | ||
1067 | # define SYMBOLIC_LINK_FLAG_DIRECTORY (0x1) | ||
1068 | #endif | ||
1069 | #ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE | ||
1070 | # define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE (0x2) | ||
1071 | #endif | ||
1072 | |||
1073 | int symlink(const char *target, const char *linkpath) | ||
1074 | { | ||
1075 | DWORD flag = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE; | ||
1076 | struct stat st; | ||
1077 | DECLARE_PROC_ADDR(BOOL, CreateSymbolicLinkA, LPCSTR, LPCSTR, DWORD); | ||
1078 | |||
1079 | if (!INIT_PROC_ADDR(kernel32.dll, CreateSymbolicLinkA)) { | ||
1080 | return -1; | ||
1081 | } | ||
1082 | |||
1083 | if (stat(target, &st) != -1 && S_ISDIR(st.st_mode)) | ||
1084 | flag |= SYMBOLIC_LINK_FLAG_DIRECTORY; | ||
1085 | |||
1086 | retry: | ||
1087 | if (!CreateSymbolicLinkA(linkpath, target, flag)) { | ||
1088 | /* Old Windows versions see 'UNPRIVILEGED_CREATE' as an invalid | ||
1089 | * parameter. Retry without it. */ | ||
1090 | if ((flag & SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) && | ||
1091 | GetLastError() == ERROR_INVALID_PARAMETER) { | ||
1092 | flag &= ~SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE; | ||
1093 | goto retry; | ||
1094 | } | ||
1095 | errno = err_win_to_posix(); | ||
1096 | return -1; | ||
1097 | } | ||
1098 | return 0; | ||
1099 | } | ||
1100 | |||
1066 | static char *normalize_ntpathA(char *buf) | 1101 | static char *normalize_ntpathA(char *buf) |
1067 | { | 1102 | { |
1068 | /* fix absolute path prefixes */ | 1103 | /* fix absolute path prefixes */ |