aboutsummaryrefslogtreecommitdiff
path: root/win32/mingw.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-02-12 14:11:01 +0000
committerRon Yorston <rmy@pobox.com>2021-02-12 14:11:01 +0000
commit7587b56c10a4d11fe434e3eaa51212113f09ec10 (patch)
tree219264f8c4079d13ab8c29d9d90f04b22e6470bc /win32/mingw.c
parent1b61a02b5139a47e2e3ac8be5afca325d7b3cea7 (diff)
downloadbusybox-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.c35
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
1073int 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
1066static char *normalize_ntpathA(char *buf) 1101static char *normalize_ntpathA(char *buf)
1067{ 1102{
1068 /* fix absolute path prefixes */ 1103 /* fix absolute path prefixes */