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
|
On Windows XP and earlier, the @exnraise[exn:fail:unsupported]. On
|
||||||
later versions of Windows, the creation of links tends to be
|
later versions of Windows, the creation of links tends to be
|
||||||
disallowed by security policies. Furthermore, a relative-path link is
|
disallowed by security policies. Windows distinguishes between file
|
||||||
parsed specially; see @secref["windowspaths"] for more information.
|
and directory links, and a directory link is created if @racket[to]
|
||||||
When @racket[make-file-or-directory-link] succeeds, it creates a symbolic
|
parses syntactically as a directory. Furthermore, a relative-path link
|
||||||
link as opposed to a junction.
|
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.}]}
|
@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,
|
static Scheme_Object *do_path_to_directory_path(char *s, intptr_t offset, intptr_t len, Scheme_Object *p, int just_check,
|
||||||
int kind)
|
int kind)
|
||||||
/* Although this function accepts an offset, the Windows part assumes that
|
/* 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;
|
char *s2;
|
||||||
#if DROP_REDUNDANT_SLASHES
|
|
||||||
int not_a_sep = 0;
|
int not_a_sep = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (kind == SCHEME_WINDOWS_PATH_KIND) {
|
if (kind == SCHEME_WINDOWS_PATH_KIND) {
|
||||||
int slash_dir_sep = 1;
|
int slash_dir_sep = 1;
|
||||||
|
@ -1937,7 +1936,7 @@ 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 (check_dos_slashslash_qm(s, len, &drive_end, NULL, NULL)) {
|
||||||
#if DROP_REDUNDANT_SLASHES
|
if (just_check > 1) {
|
||||||
if (drive_end < 0) {
|
if (drive_end < 0) {
|
||||||
/* It's a \\?\REL\ or \\?\RED\ path. */
|
/* It's a \\?\REL\ or \\?\RED\ path. */
|
||||||
int litpos;
|
int litpos;
|
||||||
|
@ -1950,23 +1949,21 @@ static Scheme_Object *do_path_to_directory_path(char *s, intptr_t offset, intptr
|
||||||
if (drive_end == len)
|
if (drive_end == len)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
|
|
||||||
/* In \\?\, / can be part of a name, and it is never a separator. */
|
/* In \\?\, / can be part of a name, and it is never a separator. */
|
||||||
slash_dir_sep = 0;
|
slash_dir_sep = 0;
|
||||||
/* Any "." or ".." at the end is a literal path element,
|
/* Any "." or ".." at the end is a literal path element,
|
||||||
not an up- or same-directory indicator: */
|
not an up- or same-directory indicator: */
|
||||||
#if DROP_REDUNDANT_SLASHES
|
|
||||||
not_a_sep = 1;
|
not_a_sep = 1;
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
#if DROP_REDUNDANT_SLASHES
|
if (just_check > 1) {
|
||||||
/* A slash after C: is not strictly necessary: */
|
/* A slash after C: is not strictly necessary: */
|
||||||
if ((len == 2)
|
if ((len == 2)
|
||||||
&& is_drive_letter(s[offset])
|
&& is_drive_letter(s[offset])
|
||||||
&& (s[offset+1] == ':'))
|
&& (s[offset+1] == ':'))
|
||||||
return p;
|
return p;
|
||||||
#endif
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -1979,7 +1976,7 @@ static Scheme_Object *do_path_to_directory_path(char *s, intptr_t offset, intptr
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DROP_REDUNDANT_SLASHES
|
if (just_check > 1) {
|
||||||
if (!not_a_sep
|
if (!not_a_sep
|
||||||
&& (((len > 1) && (s[offset + len - 1] == '.') && IS_A_SEP(kind, s[offset + len - 2]))
|
&& (((len > 1) && (s[offset + len - 1] == '.') && IS_A_SEP(kind, s[offset + len - 2]))
|
||||||
|| ((len == 1) && (s[offset] == '.'))))
|
|| ((len == 1) && (s[offset] == '.'))))
|
||||||
|
@ -2005,7 +2002,7 @@ static Scheme_Object *do_path_to_directory_path(char *s, intptr_t offset, intptr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
#endif
|
}
|
||||||
|
|
||||||
if (just_check)
|
if (just_check)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -4629,7 +4626,8 @@ static Scheme_Object *make_link(int argc, Scheme_Object *argv[])
|
||||||
|
|
||||||
|
|
||||||
#if defined(DOS_FILE_SYSTEM)
|
#if defined(DOS_FILE_SYSTEM)
|
||||||
if (do_path_to_directory_path(src, 0, -1, argv[1], 1, SCHEME_WINDOWS_PATH_KIND))
|
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;
|
dest_is_dir = 1;
|
||||||
else
|
else
|
||||||
dest_is_dir = 0;
|
dest_is_dir = 0;
|
||||||
|
|
|
@ -987,15 +987,20 @@ int rktio_make_link(rktio_t *rktio, const char *src, const char *dest, int dest_
|
||||||
#if defined(RKTIO_SYSTEM_WINDOWS)
|
#if defined(RKTIO_SYSTEM_WINDOWS)
|
||||||
init_procs();
|
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) {
|
if (CreateSymbolicLinkProc) {
|
||||||
int flags;
|
int flags = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
|
||||||
wchar_t *src_w;
|
wchar_t *src_w;
|
||||||
wchar_t *dest_w;
|
wchar_t *dest_w;
|
||||||
|
|
||||||
if (dest_is_directory)
|
if (dest_is_directory)
|
||||||
flags = 0x1; /* directory */
|
flags |= SYMBOLIC_LINK_FLAG_DIRECTORY; /* directory */
|
||||||
else
|
|
||||||
flags = 0; /* file */
|
|
||||||
|
|
||||||
src_w = WIDE_PATH_copy(src);
|
src_w = WIDE_PATH_copy(src);
|
||||||
if (!src_w) return 0;
|
if (!src_w) return 0;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user