windows: allow symlink creation when developer mode is enabled
Relevant to #3288
This commit is contained in:
parent
c8c7fd7043
commit
1a7c898ea2
|
@ -472,10 +472,15 @@ successfully,the @exnraise[exn:fail:filesystem].
|
|||
|
||||
On Windows XP and earlier, the @exnraise[exn:fail:unsupported]. On
|
||||
later versions of Windows, the creation of links tends to be
|
||||
disallowed by security policies. Furthermore, a relative-path link is
|
||||
parsed specially; see @secref["windowspaths"] for more information.
|
||||
When @racket[make-file-or-directory-link] succeeds, it creates a symbolic
|
||||
link as opposed to a junction.
|
||||
disallowed by security policies. Windows distinguishes between file
|
||||
and directory links, and a directory link is created if @racket[to]
|
||||
parses syntactically as a directory. Furthermore, a relative-path link
|
||||
is parsed specially by the operating system; see
|
||||
@secref["windowspaths"] for more information. When
|
||||
@racket[make-file-or-directory-link] succeeds, it creates a symbolic
|
||||
link as opposed to a junction or hard link. Beware that directory
|
||||
links must be deleted using @racket[delete-directory] instead of
|
||||
@racket[delete-file].
|
||||
|
||||
@history[#:changed "6.0.1.12" @elem{Added support for links on Windows.}]}
|
||||
|
||||
|
|
|
@ -1919,12 +1919,11 @@ static int path_is_simple_dir_without_sep(Scheme_Object *path)
|
|||
static Scheme_Object *do_path_to_directory_path(char *s, intptr_t offset, intptr_t len, Scheme_Object *p, int just_check,
|
||||
int kind)
|
||||
/* Although this function accepts an offset, the Windows part assumes that
|
||||
`offset' is always 0. */
|
||||
`offset' is always 0. If `just_check` is > 1, returns `p` for more
|
||||
directory paths than just the ones that end in a separator. */
|
||||
{
|
||||
char *s2;
|
||||
#if DROP_REDUNDANT_SLASHES
|
||||
int not_a_sep = 0;
|
||||
#endif
|
||||
|
||||
if (kind == SCHEME_WINDOWS_PATH_KIND) {
|
||||
int slash_dir_sep = 1;
|
||||
|
@ -1937,36 +1936,34 @@ static Scheme_Object *do_path_to_directory_path(char *s, intptr_t offset, intptr
|
|||
}
|
||||
|
||||
if (check_dos_slashslash_qm(s, len, &drive_end, NULL, NULL)) {
|
||||
#if DROP_REDUNDANT_SLASHES
|
||||
if (drive_end < 0) {
|
||||
/* It's a \\?\REL\ or \\?\RED\ path. */
|
||||
int litpos;
|
||||
drive_end = get_slashslash_qm_dot_ups_end(s, len, &litpos);
|
||||
/* If there's no path after the ..s, then nothing more is needed. */
|
||||
if (litpos >= len)
|
||||
return p;
|
||||
} else {
|
||||
/* If s is just a drive, then nothing more is needed. */
|
||||
if (drive_end == len)
|
||||
return p;
|
||||
if (just_check > 1) {
|
||||
if (drive_end < 0) {
|
||||
/* It's a \\?\REL\ or \\?\RED\ path. */
|
||||
int litpos;
|
||||
drive_end = get_slashslash_qm_dot_ups_end(s, len, &litpos);
|
||||
/* If there's no path after the ..s, then nothing more is needed. */
|
||||
if (litpos >= len)
|
||||
return p;
|
||||
} else {
|
||||
/* If s is just a drive, then nothing more is needed. */
|
||||
if (drive_end == len)
|
||||
return p;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* In \\?\, / can be part of a name, and it is never a separator. */
|
||||
slash_dir_sep = 0;
|
||||
/* Any "." or ".." at the end is a literal path element,
|
||||
not an up- or same-directory indicator: */
|
||||
#if DROP_REDUNDANT_SLASHES
|
||||
not_a_sep = 1;
|
||||
#endif
|
||||
} else {
|
||||
#if DROP_REDUNDANT_SLASHES
|
||||
/* A slash after C: is not strictly necessary: */
|
||||
if ((len == 2)
|
||||
&& is_drive_letter(s[offset])
|
||||
&& (s[offset+1] == ':'))
|
||||
return p;
|
||||
#endif
|
||||
if (just_check > 1) {
|
||||
/* A slash after C: is not strictly necessary: */
|
||||
if ((len == 2)
|
||||
&& is_drive_letter(s[offset])
|
||||
&& (s[offset+1] == ':'))
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
|
@ -1979,33 +1976,33 @@ static Scheme_Object *do_path_to_directory_path(char *s, intptr_t offset, intptr
|
|||
return p;
|
||||
}
|
||||
|
||||
#if DROP_REDUNDANT_SLASHES
|
||||
if (!not_a_sep
|
||||
&& (((len > 1) && (s[offset + len - 1] == '.') && IS_A_SEP(kind, s[offset + len - 2]))
|
||||
|| ((len == 1) && (s[offset] == '.'))))
|
||||
return p;
|
||||
if (!not_a_sep
|
||||
&& (((len > 2)
|
||||
&& (s[offset + len - 1] == '.')
|
||||
&& (s[offset + len - 2] == '.')
|
||||
&& IS_A_SEP(kind, s[offset + len - 3]))
|
||||
|| ((len == 2) && (s[offset] == '.') && (s[offset + 1] == '.'))))
|
||||
return p;
|
||||
if (just_check > 1) {
|
||||
if (!not_a_sep
|
||||
&& (((len > 1) && (s[offset + len - 1] == '.') && IS_A_SEP(kind, s[offset + len - 2]))
|
||||
|| ((len == 1) && (s[offset] == '.'))))
|
||||
return p;
|
||||
if (!not_a_sep
|
||||
&& (((len > 2)
|
||||
&& (s[offset + len - 1] == '.')
|
||||
&& (s[offset + len - 2] == '.')
|
||||
&& IS_A_SEP(kind, s[offset + len - 3]))
|
||||
|| ((len == 2) && (s[offset] == '.') && (s[offset + 1] == '.'))))
|
||||
return p;
|
||||
|
||||
# ifdef TILDE_IS_ABSOLUTE
|
||||
if (kind == SCHEME_UNIX_PATH_KIND) {
|
||||
if (s[offset] == '~') {
|
||||
intptr_t i;
|
||||
for (i = 1; i < len; i++) {
|
||||
if (IS_A_UNIX_SEP(s[offset + i]))
|
||||
break;
|
||||
if (kind == SCHEME_UNIX_PATH_KIND) {
|
||||
if (s[offset] == '~') {
|
||||
intptr_t i;
|
||||
for (i = 1; i < len; i++) {
|
||||
if (IS_A_UNIX_SEP(s[offset + i]))
|
||||
break;
|
||||
}
|
||||
if (i >= len)
|
||||
return p;
|
||||
}
|
||||
if (i >= len)
|
||||
return p;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
if (just_check)
|
||||
return NULL;
|
||||
|
@ -4629,10 +4626,11 @@ static Scheme_Object *make_link(int argc, Scheme_Object *argv[])
|
|||
|
||||
|
||||
#if defined(DOS_FILE_SYSTEM)
|
||||
if (do_path_to_directory_path(src, 0, -1, argv[1], 1, SCHEME_WINDOWS_PATH_KIND))
|
||||
dest_is_dir = 1;
|
||||
if (do_path_to_directory_path(SCHEME_PATH_VAL(dest), 0, SCHEME_PATH_LEN(dest),
|
||||
argv[0], 2, SCHEME_WINDOWS_PATH_KIND))
|
||||
dest_is_dir = 1;
|
||||
else
|
||||
dest_is_dir = 0;
|
||||
dest_is_dir = 0;
|
||||
#else
|
||||
dest_is_dir = 0;
|
||||
#endif
|
||||
|
|
|
@ -987,15 +987,20 @@ int rktio_make_link(rktio_t *rktio, const char *src, const char *dest, int dest_
|
|||
#if defined(RKTIO_SYSTEM_WINDOWS)
|
||||
init_procs();
|
||||
|
||||
# ifndef SYMBOLIC_LINK_FLAG_DIRECTORY
|
||||
# define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1
|
||||
# endif
|
||||
# ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
|
||||
# define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x2
|
||||
# endif
|
||||
|
||||
if (CreateSymbolicLinkProc) {
|
||||
int flags;
|
||||
int flags = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
|
||||
wchar_t *src_w;
|
||||
wchar_t *dest_w;
|
||||
|
||||
if (dest_is_directory)
|
||||
flags = 0x1; /* directory */
|
||||
else
|
||||
flags = 0; /* file */
|
||||
flags |= SYMBOLIC_LINK_FLAG_DIRECTORY; /* directory */
|
||||
|
||||
src_w = WIDE_PATH_copy(src);
|
||||
if (!src_w) return 0;
|
||||
|
|
Loading…
Reference in New Issue
Block a user