* autoload.cc (CreateSymbolicLink): Define.
* environ.cc (set_winsymlinks): Set allow_winsymlinks. (parse_thing): Change "winsymlinks" to set by function. * globals.cc (enum winsym_t): Define. (allow_winsymlinks): Define as winsym_t. (ro_u_afs): New R/O Unicode string. * mount.cc (fs_info::update): Fix comment. Handle AFS. (fs_names): Add "afs". * mount.h (enum fs_info_type): Add afs. (class fs_info): Implement afs. * path.cc (symlink): Drop third parameter in call to symlink_worker. (symlink_nfs): New function. (symlink_native): New function. (symlink_worker): Drop third argument. Handle native symlink type by calling symlink_native. Move code to handle NFS to symlink_nfs. Fix formatting. Slightly restructure code. * path.h (class path_conv): Add fs_is_afs method. (symlink_worker): Declare here. * security.h: Define privilege constants as unsigned int instead of as unsigned long. * syscalls.cc (mknod_worker): Set third parameter in symlink_worker call to WSYM_lnk. * winsup.h (symlink_worker): Drop declaration here.
This commit is contained in:
parent
bd91f4a96a
commit
9ecd475cd8
|
@ -1,3 +1,29 @@
|
|||
2013-04-23 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* autoload.cc (CreateSymbolicLink): Define.
|
||||
* environ.cc (set_winsymlinks): Set allow_winsymlinks.
|
||||
(parse_thing): Change "winsymlinks" to set by function.
|
||||
* globals.cc (enum winsym_t): Define.
|
||||
(allow_winsymlinks): Define as winsym_t.
|
||||
(ro_u_afs): New R/O Unicode string.
|
||||
* mount.cc (fs_info::update): Fix comment. Handle AFS.
|
||||
(fs_names): Add "afs".
|
||||
* mount.h (enum fs_info_type): Add afs.
|
||||
(class fs_info): Implement afs.
|
||||
* path.cc (symlink): Drop third parameter in call to symlink_worker.
|
||||
(symlink_nfs): New function.
|
||||
(symlink_native): New function.
|
||||
(symlink_worker): Drop third argument. Handle native symlink type by
|
||||
calling symlink_native. Move code to handle NFS to symlink_nfs. Fix
|
||||
formatting. Slightly restructure code.
|
||||
* path.h (class path_conv): Add fs_is_afs method.
|
||||
(symlink_worker): Declare here.
|
||||
* security.h: Define privilege constants as unsigned int instead of as
|
||||
unsigned long.
|
||||
* syscalls.cc (mknod_worker): Set third parameter in symlink_worker
|
||||
call to WSYM_lnk.
|
||||
* winsup.h (symlink_worker): Drop declaration here.
|
||||
|
||||
2013-04-23 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* cygwin64.din (_setjmp): Export.
|
||||
|
|
|
@ -574,6 +574,7 @@ LoadDLLfunc (GetIpForwardTable, 12, iphlpapi)
|
|||
LoadDLLfunc (GetNetworkParams, 8, iphlpapi)
|
||||
LoadDLLfunc (GetUdpTable, 12, iphlpapi)
|
||||
|
||||
LoadDLLfunc (CreateSymbolicLink, 12, kernel32)
|
||||
LoadDLLfuncEx (GetNamedPipeClientProcessId, 8, kernel32, 1)
|
||||
LoadDLLfunc (LocaleNameToLCID, 8, kernel32)
|
||||
|
||||
|
|
|
@ -89,6 +89,19 @@ tty_is_gone (const char *buf)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_winsymlinks (const char *buf)
|
||||
{
|
||||
if (!buf || !*buf)
|
||||
allow_winsymlinks = WSYM_lnk;
|
||||
else if (ascii_strncasematch (buf, "lnk", 3))
|
||||
allow_winsymlinks = WSYM_lnk;
|
||||
/* Make sure to try native symlinks only on systems supporting them. */
|
||||
else if (ascii_strncasematch (buf, "native", 6)
|
||||
&& wincap.max_sys_priv () >= SE_CREATE_SYMBOLIC_LINK_PRIVILEGE)
|
||||
allow_winsymlinks = WSYM_native;
|
||||
}
|
||||
|
||||
/* The structure below is used to set up an array which is used to
|
||||
parse the CYGWIN environment variable or, if enabled, options from
|
||||
the registry. */
|
||||
|
@ -121,7 +134,7 @@ static struct parse_thing
|
|||
{"proc_retry", {func: set_proc_retry}, isfunc, NULL, {{0}, {5}}},
|
||||
{"reset_com", {&reset_com}, setbool, NULL, {{false}, {true}}},
|
||||
{"tty", {func: tty_is_gone}, isfunc, NULL, {{0}, {0}}},
|
||||
{"winsymlinks", {&allow_winsymlinks}, setbool, NULL, {{false}, {true}}},
|
||||
{"winsymlinks", {func: set_winsymlinks}, isfunc, NULL, {{0}, {0}}},
|
||||
{NULL, {0}, setdword, 0, {{0}, {0}}}
|
||||
};
|
||||
|
||||
|
|
|
@ -49,6 +49,16 @@ enum exit_states
|
|||
ES_FINAL
|
||||
};
|
||||
|
||||
/* The type of symlink to create. The value is set depending on the
|
||||
"winsymlinks" setting of the CYGWIN environment variable. */
|
||||
enum winsym_t
|
||||
{
|
||||
WSYM_sysfile = 0,
|
||||
WSYM_lnk,
|
||||
WSYM_native,
|
||||
WSYM_nfs
|
||||
};
|
||||
|
||||
exit_states NO_COPY exit_state;
|
||||
|
||||
/* Set in init.cc. Used to check if Cygwin DLL is dynamically loaded. */
|
||||
|
@ -58,7 +68,7 @@ int NO_COPY dynamically_loaded;
|
|||
bool allow_glob = true;
|
||||
bool ignore_case_with_glob = false;
|
||||
bool dos_file_warning = true;
|
||||
bool allow_winsymlinks = false;
|
||||
winsym_t allow_winsymlinks = WSYM_sysfile;
|
||||
bool reset_com = false;
|
||||
bool pipe_byte = false;
|
||||
bool detect_bloda = false;
|
||||
|
@ -124,6 +134,7 @@ extern "C" {
|
|||
extern UNICODE_STRING _RDATA ro_u_unixfs = _ROU (L"UNIXFS");
|
||||
extern UNICODE_STRING _RDATA ro_u_nwfs = _ROU (L"NWFS");
|
||||
extern UNICODE_STRING _RDATA ro_u_ncfsd = _ROU (L"NcFsd");
|
||||
extern UNICODE_STRING _RDATA ro_u_afs = _ROU (L"AFSRDRFsd");
|
||||
extern UNICODE_STRING _RDATA ro_u_volume = _ROU (L"\\??\\Volume{");
|
||||
extern UNICODE_STRING _RDATA ro_u_pipedir = _ROU (L"\\\\?\\PIPE\\");
|
||||
extern UNICODE_STRING _RDATA ro_u_globalroot = _ROU (L"\\\\.\\GLOBALROOT");
|
||||
|
|
|
@ -275,7 +275,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
|||
if (is_remote_drive ())
|
||||
{
|
||||
/* Should be reevaluated for each new OS. Right now this mask is valid up
|
||||
to Vista. The important point here is to test only flags indicating
|
||||
to Windows 8. The important point here is to test only flags indicating
|
||||
capabilities and to ignore flags indicating a specific state of this
|
||||
volume. At present these flags to ignore are FILE_VOLUME_IS_COMPRESSED,
|
||||
FILE_READ_ONLY_VOLUME, and FILE_SEQUENTIAL_WRITE_ONCE. The additional
|
||||
|
@ -371,7 +371,10 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
|||
&& !is_ncfsd (RtlEqualUnicodeString (&fsname, &ro_u_ncfsd, FALSE))
|
||||
/* UNIXFS == TotalNet Advanced Server (TAS). Doesn't support
|
||||
FileIdBothDirectoryInformation. See below. */
|
||||
&& !is_unixfs (RtlEqualUnicodeString (&fsname, &ro_u_unixfs, FALSE)))
|
||||
&& !is_unixfs (RtlEqualUnicodeString (&fsname, &ro_u_unixfs, FALSE))
|
||||
/* AFSRDRFsd == Andrew File System. Doesn't support DOS attributes.
|
||||
Only native symlinks are supported. */
|
||||
&& !is_afs (RtlEqualUnicodeString (&fsname, &ro_u_afs, FALSE)))
|
||||
{
|
||||
/* Known remote file system with buggy open calls. Further
|
||||
explanation in fhandler.cc (fhandler_disk_file::open_fs). */
|
||||
|
@ -1598,6 +1601,7 @@ fs_names_t fs_names[] = {
|
|||
{ "cifs", false },
|
||||
{ "nwfs", false },
|
||||
{ "ncfsd", false },
|
||||
{ "afs", false },
|
||||
{ NULL, false }
|
||||
};
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ enum fs_info_type
|
|||
cifs,
|
||||
nwfs,
|
||||
ncfsd,
|
||||
afs,
|
||||
/* Always last. */
|
||||
max_fs_type
|
||||
};
|
||||
|
@ -114,6 +115,7 @@ class fs_info
|
|||
IMPLEMENT_FS_FLAG (cifs)
|
||||
IMPLEMENT_FS_FLAG (nwfs)
|
||||
IMPLEMENT_FS_FLAG (ncfsd)
|
||||
IMPLEMENT_FS_FLAG (afs)
|
||||
fs_info_type what_fs () const { return status.fs_type; }
|
||||
bool got_fs () const { return status.fs_type != none; }
|
||||
|
||||
|
|
|
@ -1475,27 +1475,98 @@ conv_path_list (const char *src, char *dst, size_t size,
|
|||
extern "C" int
|
||||
symlink (const char *oldpath, const char *newpath)
|
||||
{
|
||||
return symlink_worker (oldpath, newpath, allow_winsymlinks, false);
|
||||
return symlink_worker (oldpath, newpath, false);
|
||||
}
|
||||
|
||||
static int
|
||||
symlink_nfs (const char *oldpath, path_conv &win32_newpath)
|
||||
{
|
||||
/* On NFS, create symlinks by calling NtCreateFile with an EA of type
|
||||
NfsSymlinkTargetName containing ... the symlink target name. */
|
||||
tmp_pathbuf tp;
|
||||
PFILE_FULL_EA_INFORMATION pffei;
|
||||
NTSTATUS status;
|
||||
HANDLE fh;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
|
||||
pffei = (PFILE_FULL_EA_INFORMATION) tp.w_get ();
|
||||
pffei->NextEntryOffset = 0;
|
||||
pffei->Flags = 0;
|
||||
pffei->EaNameLength = sizeof (NFS_SYML_TARGET) - 1;
|
||||
char *EaValue = stpcpy (pffei->EaName, NFS_SYML_TARGET) + 1;
|
||||
pffei->EaValueLength = sizeof (WCHAR) *
|
||||
(sys_mbstowcs ((PWCHAR) EaValue, NT_MAX_PATH, oldpath) - 1);
|
||||
status = NtCreateFile (&fh, FILE_WRITE_DATA | FILE_WRITE_EA | SYNCHRONIZE,
|
||||
win32_newpath.get_object_attr (attr, sec_none_nih),
|
||||
&io, NULL, FILE_ATTRIBUTE_SYSTEM,
|
||||
FILE_SHARE_VALID_FLAGS, FILE_CREATE,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT
|
||||
| FILE_OPEN_FOR_BACKUP_INTENT,
|
||||
pffei, NT_MAX_PATH * sizeof (WCHAR));
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
__seterrno_from_nt_status (status);
|
||||
return -1;
|
||||
}
|
||||
NtClose (fh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
symlink_native (const char *oldpath, path_conv &win32_newpath)
|
||||
{
|
||||
tmp_pathbuf tp;
|
||||
path_conv win32_oldpath;
|
||||
PUNICODE_STRING final_oldpath, final_newpath;
|
||||
|
||||
if (isabspath (oldpath))
|
||||
{
|
||||
win32_oldpath.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
|
||||
final_oldpath = win32_oldpath.get_nt_native_path ();
|
||||
final_oldpath->Buffer[1] = L'\\';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The symlink target is relative to the directory in which
|
||||
the symlink gets created, not relative to the cwd. Therefore
|
||||
we have to mangle the path quite a bit before calling path_conv. */
|
||||
ssize_t len = strrchr (win32_newpath.normalized_path, '/')
|
||||
- win32_newpath.normalized_path + 1;
|
||||
char *absoldpath = tp.t_get ();
|
||||
stpcpy (stpncpy (absoldpath, win32_newpath.normalized_path, len),
|
||||
oldpath);
|
||||
win32_oldpath.check (absoldpath, PC_SYM_NOFOLLOW, stat_suffixes);
|
||||
UNICODE_STRING dirpath;
|
||||
RtlSplitUnicodePath (win32_newpath.get_nt_native_path (), &dirpath, NULL);
|
||||
final_oldpath = win32_oldpath.get_nt_native_path ();
|
||||
final_oldpath->Buffer += dirpath.Length / sizeof (WCHAR);
|
||||
}
|
||||
final_newpath = win32_newpath.get_nt_native_path ();
|
||||
/* Convert native to DOS UNC path. */
|
||||
final_newpath->Buffer[1] = L'\\';
|
||||
if (!CreateSymbolicLinkW (final_newpath->Buffer, final_oldpath->Buffer,
|
||||
win32_oldpath.isdir ()
|
||||
? SYMBOLIC_LINK_FLAG_DIRECTORY : 0))
|
||||
{
|
||||
/* Repair native path, we still need it. */
|
||||
final_newpath->Buffer[1] = L'?';
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
|
||||
bool isdevice)
|
||||
symlink_worker (const char *oldpath, const char *newpath, bool isdevice)
|
||||
{
|
||||
int res = -1;
|
||||
size_t len;
|
||||
path_conv win32_newpath, win32_oldpath;
|
||||
path_conv win32_newpath;
|
||||
char *buf, *cp;
|
||||
SECURITY_ATTRIBUTES sa = sec_none_nih;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
NTSTATUS status;
|
||||
HANDLE fh;
|
||||
ULONG access = DELETE | FILE_GENERIC_WRITE;
|
||||
tmp_pathbuf tp;
|
||||
unsigned check_opt;
|
||||
bool mk_winsym = use_winsym;
|
||||
bool has_trailing_dirsep = false;
|
||||
winsym_t wsym_type;
|
||||
|
||||
/* POSIX says that empty 'newpath' is invalid input while empty
|
||||
'oldpath' is valid -- it's symlink resolver job to verify if
|
||||
|
@ -1527,11 +1598,35 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
|
|||
check_opt = PC_SYM_NOFOLLOW | PC_POSIX | (isdevice ? PC_NOWARN : 0);
|
||||
/* We need the normalized full path below. */
|
||||
win32_newpath.check (newpath, check_opt, stat_suffixes);
|
||||
|
||||
/* Default symlink type is determined by global allow_winsymlinks variable.
|
||||
Device files are always shortcuts. */
|
||||
wsym_type = isdevice ? WSYM_lnk : allow_winsymlinks;
|
||||
/* NFS has its own, dedicated way to create symlinks. */
|
||||
if (win32_newpath.fs_is_nfs ())
|
||||
wsym_type = WSYM_nfs;
|
||||
/* MVFS doesn't handle the SYSTEM DOS attribute, but it handles the R/O
|
||||
attribute. Therefore we create symlinks on MVFS always as shortcuts. */
|
||||
mk_winsym |= win32_newpath.fs_is_mvfs ();
|
||||
else if (win32_newpath.fs_is_mvfs ())
|
||||
wsym_type = WSYM_lnk;
|
||||
/* AFS only supports native symlinks. */
|
||||
else if (win32_newpath.fs_is_afs ())
|
||||
{
|
||||
/* Bail out if OS doesn't support native symlinks. */
|
||||
if (wincap.max_sys_priv () < SE_CREATE_SYMBOLIC_LINK_PRIVILEGE)
|
||||
{
|
||||
set_errno (EPERM);
|
||||
goto done;
|
||||
}
|
||||
wsym_type = WSYM_native;
|
||||
}
|
||||
/* Don't try native symlinks on filesystems not supporting reparse points. */
|
||||
else if (wsym_type == WSYM_native
|
||||
&& !(win32_newpath.fs_flags () & FILE_SUPPORTS_REPARSE_POINTS))
|
||||
wsym_type = WSYM_sysfile;
|
||||
|
||||
if (mk_winsym && !win32_newpath.exists ()
|
||||
/* Attach .lnk suffix when shortcut is requested. */
|
||||
if (wsym_type == WSYM_lnk && !win32_newpath.exists ()
|
||||
&& (isdevice || !win32_newpath.fs_is_nfs ()))
|
||||
{
|
||||
char *newplnk = tp.c_get ();
|
||||
|
@ -1545,8 +1640,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
|
|||
goto done;
|
||||
}
|
||||
|
||||
syscall_printf ("symlink (%s, %S)", oldpath,
|
||||
win32_newpath.get_nt_native_path ());
|
||||
syscall_printf ("symlink (%s, %S) wsym_type %d", oldpath,
|
||||
win32_newpath.get_nt_native_path (), wsym_type);
|
||||
|
||||
if ((!isdevice && win32_newpath.exists ())
|
||||
|| win32_newpath.is_auto_device ())
|
||||
|
@ -1560,36 +1655,29 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (!isdevice && win32_newpath.fs_is_nfs ())
|
||||
/* Handle NFS and native symlinks in their own functions. */
|
||||
switch (wsym_type)
|
||||
{
|
||||
/* On NFS, create symlinks by calling NtCreateFile with an EA of type
|
||||
NfsSymlinkTargetName containing ... the symlink target name. */
|
||||
PFILE_FULL_EA_INFORMATION pffei = (PFILE_FULL_EA_INFORMATION) tp.w_get ();
|
||||
pffei->NextEntryOffset = 0;
|
||||
pffei->Flags = 0;
|
||||
pffei->EaNameLength = sizeof (NFS_SYML_TARGET) - 1;
|
||||
char *EaValue = stpcpy (pffei->EaName, NFS_SYML_TARGET) + 1;
|
||||
pffei->EaValueLength = sizeof (WCHAR) *
|
||||
(sys_mbstowcs ((PWCHAR) EaValue, NT_MAX_PATH, oldpath) - 1);
|
||||
status = NtCreateFile (&fh, FILE_WRITE_DATA | FILE_WRITE_EA | SYNCHRONIZE,
|
||||
win32_newpath.get_object_attr (attr, sa),
|
||||
&io, NULL, FILE_ATTRIBUTE_SYSTEM,
|
||||
FILE_SHARE_VALID_FLAGS, FILE_CREATE,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT
|
||||
| FILE_OPEN_FOR_BACKUP_INTENT,
|
||||
pffei, NT_MAX_PATH * sizeof (WCHAR));
|
||||
if (!NT_SUCCESS (status))
|
||||
case WSYM_nfs:
|
||||
res = symlink_nfs (oldpath, win32_newpath);
|
||||
goto done;
|
||||
case WSYM_native:
|
||||
res = symlink_native (oldpath, win32_newpath);
|
||||
/* AFS? Too bad. Otherwise, just try the default symlink type. */
|
||||
if (win32_newpath.fs_is_afs ())
|
||||
{
|
||||
__seterrno_from_nt_status (status);
|
||||
__seterrno ();
|
||||
goto done;
|
||||
}
|
||||
NtClose (fh);
|
||||
res = 0;
|
||||
goto done;
|
||||
wsym_type = WSYM_sysfile;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (mk_winsym)
|
||||
if (wsym_type == WSYM_lnk)
|
||||
{
|
||||
path_conv win32_oldpath;
|
||||
ITEMIDLIST *pidl = NULL;
|
||||
size_t full_len = 0;
|
||||
unsigned short oldpath_len, desc_len, relpath_len, pidl_len = 0;
|
||||
|
@ -1604,11 +1692,11 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
|
|||
/* The symlink target is relative to the directory in which
|
||||
the symlink gets created, not relative to the cwd. Therefore
|
||||
we have to mangle the path quite a bit before calling path_conv. */
|
||||
if (isabspath (oldpath))
|
||||
win32_oldpath.check (oldpath,
|
||||
PC_SYM_NOFOLLOW,
|
||||
stat_suffixes);
|
||||
else
|
||||
if (isabspath (oldpath))
|
||||
win32_oldpath.check (oldpath,
|
||||
PC_SYM_NOFOLLOW,
|
||||
stat_suffixes);
|
||||
else
|
||||
{
|
||||
len = strrchr (win32_newpath.normalized_path, '/')
|
||||
- win32_newpath.normalized_path + 1;
|
||||
|
@ -1677,7 +1765,7 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
|
|||
full_len += sizeof (unsigned short) + oldpath_len;
|
||||
/* 1 byte more for trailing 0 written by stpcpy. */
|
||||
if (full_len < NT_MAX_PATH * sizeof (WCHAR))
|
||||
buf = (char *) tp.w_get ();
|
||||
buf = tp.t_get ();
|
||||
else
|
||||
buf = (char *) alloca (full_len + 1);
|
||||
|
||||
|
@ -1721,7 +1809,7 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
|
|||
else
|
||||
{
|
||||
/* Default technique creating a symlink. */
|
||||
buf = (char *) tp.w_get ();
|
||||
buf = tp.t_get ();
|
||||
cp = stpcpy (buf, SYMLINK_COOKIE);
|
||||
*(PWCHAR) cp = 0xfeff; /* BOM */
|
||||
cp += 2;
|
||||
|
@ -1729,10 +1817,17 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
|
|||
cp += sys_mbstowcs ((PWCHAR) cp, NT_MAX_PATH, oldpath) * sizeof (WCHAR);
|
||||
}
|
||||
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
NTSTATUS status;
|
||||
ULONG access;
|
||||
HANDLE fh;
|
||||
|
||||
access = DELETE | FILE_GENERIC_WRITE;
|
||||
if (isdevice && win32_newpath.exists ())
|
||||
{
|
||||
status = NtOpenFile (&fh, FILE_WRITE_ATTRIBUTES,
|
||||
win32_newpath.get_object_attr (attr, sa),
|
||||
win32_newpath.get_object_attr (attr, sec_none_nih),
|
||||
&io, 0, FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
|
@ -1758,7 +1853,7 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
|
|||
so for now we don't request WRITE_DAC on remote drives. */
|
||||
access |= READ_CONTROL | WRITE_DAC;
|
||||
|
||||
status = NtCreateFile (&fh, access, win32_newpath.get_object_attr (attr, sa),
|
||||
status = NtCreateFile (&fh, access, win32_newpath.get_object_attr (attr, sec_none_nih),
|
||||
&io, NULL, FILE_ATTRIBUTE_NORMAL,
|
||||
FILE_SHARE_VALID_FLAGS,
|
||||
isdevice ? FILE_OVERWRITE_IF : FILE_CREATE,
|
||||
|
@ -1778,8 +1873,9 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
|
|||
status = NtWriteFile (fh, NULL, NULL, NULL, &io, buf, cp - buf, NULL, NULL);
|
||||
if (NT_SUCCESS (status) && io.Information == (ULONG) (cp - buf))
|
||||
{
|
||||
status = NtSetAttributesFile (fh, mk_winsym ? FILE_ATTRIBUTE_READONLY
|
||||
: FILE_ATTRIBUTE_SYSTEM);
|
||||
status = NtSetAttributesFile (fh, wsym_type == WSYM_lnk
|
||||
? FILE_ATTRIBUTE_READONLY
|
||||
: FILE_ATTRIBUTE_SYSTEM);
|
||||
if (!NT_SUCCESS (status))
|
||||
debug_printf ("Setting attributes failed, status = %y", status);
|
||||
res = 0;
|
||||
|
@ -1796,8 +1892,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
|
|||
NtClose (fh);
|
||||
|
||||
done:
|
||||
syscall_printf ("%d = symlink_worker(%s, %s, %d, %d)", res, oldpath,
|
||||
newpath, mk_winsym, isdevice);
|
||||
syscall_printf ("%d = symlink_worker(%s, %s, %d)",
|
||||
res, oldpath, newpath, isdevice);
|
||||
if (has_trailing_dirsep)
|
||||
free ((void *) newpath);
|
||||
return res;
|
||||
|
|
|
@ -382,6 +382,7 @@ class path_conv
|
|||
bool fs_is_cifs () const {return fs.is_cifs ();}
|
||||
bool fs_is_nwfs () const {return fs.is_nwfs ();}
|
||||
bool fs_is_ncfsd () const {return fs.is_ncfsd ();}
|
||||
bool fs_is_afs () const {return fs.is_afs ();}
|
||||
fs_info_type fs_type () const {return fs.what_fs ();}
|
||||
ULONG fs_serial_number () const {return fs.serial_number ();}
|
||||
inline const char *set_path (const char *p)
|
||||
|
@ -473,3 +474,5 @@ class etc
|
|||
static bool test_file_change (int);
|
||||
friend class pwdgrp;
|
||||
};
|
||||
|
||||
int __reg3 symlink_worker (const char *, const char *, bool);
|
||||
|
|
|
@ -30,41 +30,41 @@ details. */
|
|||
#define NO_SID ((PSID)NULL)
|
||||
|
||||
#ifndef SE_CREATE_TOKEN_PRIVILEGE
|
||||
#define SE_CREATE_TOKEN_PRIVILEGE 2UL
|
||||
#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE 3UL
|
||||
#define SE_LOCK_MEMORY_PRIVILEGE 4UL
|
||||
#define SE_INCREASE_QUOTA_PRIVILEGE 5UL
|
||||
#define SE_MACHINE_ACCOUNT_PRIVILEGE 6UL
|
||||
#define SE_TCB_PRIVILEGE 7UL
|
||||
#define SE_SECURITY_PRIVILEGE 8UL
|
||||
#define SE_TAKE_OWNERSHIP_PRIVILEGE 9UL
|
||||
#define SE_LOAD_DRIVER_PRIVILEGE 10UL
|
||||
#define SE_SYSTEM_PROFILE_PRIVILEGE 11UL
|
||||
#define SE_SYSTEMTIME_PRIVILEGE 12UL
|
||||
#define SE_PROF_SINGLE_PROCESS_PRIVILEGE 13UL
|
||||
#define SE_INC_BASE_PRIORITY_PRIVILEGE 14UL
|
||||
#define SE_CREATE_PAGEFILE_PRIVILEGE 15UL
|
||||
#define SE_CREATE_PERMANENT_PRIVILEGE 16UL
|
||||
#define SE_BACKUP_PRIVILEGE 17UL
|
||||
#define SE_RESTORE_PRIVILEGE 18UL
|
||||
#define SE_SHUTDOWN_PRIVILEGE 19UL
|
||||
#define SE_DEBUG_PRIVILEGE 20UL
|
||||
#define SE_AUDIT_PRIVILEGE 21UL
|
||||
#define SE_SYSTEM_ENVIRONMENT_PRIVILEGE 22UL
|
||||
#define SE_CHANGE_NOTIFY_PRIVILEGE 23UL
|
||||
#define SE_REMOTE_SHUTDOWN_PRIVILEGE 24UL
|
||||
#define SE_UNDOCK_PRIVILEGE 25UL
|
||||
#define SE_SYNC_AGENT_PRIVILEGE 26UL
|
||||
#define SE_ENABLE_DELEGATION_PRIVILEGE 27UL
|
||||
#define SE_MANAGE_VOLUME_PRIVILEGE 28UL
|
||||
#define SE_IMPERSONATE_PRIVILEGE 29UL
|
||||
#define SE_CREATE_GLOBAL_PRIVILEGE 30UL
|
||||
#define SE_CREATE_TOKEN_PRIVILEGE 2U
|
||||
#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE 3U
|
||||
#define SE_LOCK_MEMORY_PRIVILEGE 4U
|
||||
#define SE_INCREASE_QUOTA_PRIVILEGE 5U
|
||||
#define SE_MACHINE_ACCOUNT_PRIVILEGE 6U
|
||||
#define SE_TCB_PRIVILEGE 7U
|
||||
#define SE_SECURITY_PRIVILEGE 8U
|
||||
#define SE_TAKE_OWNERSHIP_PRIVILEGE 9U
|
||||
#define SE_LOAD_DRIVER_PRIVILEGE 10U
|
||||
#define SE_SYSTEM_PROFILE_PRIVILEGE 11U
|
||||
#define SE_SYSTEMTIME_PRIVILEGE 12U
|
||||
#define SE_PROF_SINGLE_PROCESS_PRIVILEGE 13U
|
||||
#define SE_INC_BASE_PRIORITY_PRIVILEGE 14U
|
||||
#define SE_CREATE_PAGEFILE_PRIVILEGE 15U
|
||||
#define SE_CREATE_PERMANENT_PRIVILEGE 16U
|
||||
#define SE_BACKUP_PRIVILEGE 17U
|
||||
#define SE_RESTORE_PRIVILEGE 18U
|
||||
#define SE_SHUTDOWN_PRIVILEGE 19U
|
||||
#define SE_DEBUG_PRIVILEGE 20U
|
||||
#define SE_AUDIT_PRIVILEGE 21U
|
||||
#define SE_SYSTEM_ENVIRONMENT_PRIVILEGE 22U
|
||||
#define SE_CHANGE_NOTIFY_PRIVILEGE 23U
|
||||
#define SE_REMOTE_SHUTDOWN_PRIVILEGE 24U
|
||||
#define SE_UNDOCK_PRIVILEGE 25U
|
||||
#define SE_SYNC_AGENT_PRIVILEGE 26U
|
||||
#define SE_ENABLE_DELEGATION_PRIVILEGE 27U
|
||||
#define SE_MANAGE_VOLUME_PRIVILEGE 28U
|
||||
#define SE_IMPERSONATE_PRIVILEGE 29U
|
||||
#define SE_CREATE_GLOBAL_PRIVILEGE 30U
|
||||
/* Starting with Vista */
|
||||
#define SE_TRUSTED_CREDMAN_ACCESS_PRIVILEGE 31UL
|
||||
#define SE_RELABEL_PRIVILEGE 32UL
|
||||
#define SE_INCREASE_WORKING_SET_PRIVILEGE 33UL
|
||||
#define SE_TIME_ZONE_PRIVILEGE 34UL
|
||||
#define SE_CREATE_SYMBOLIC_LINK_PRIVILEGE 35UL
|
||||
#define SE_TRUSTED_CREDMAN_ACCESS_PRIVILEGE 31U
|
||||
#define SE_RELABEL_PRIVILEGE 32U
|
||||
#define SE_INCREASE_WORKING_SET_PRIVILEGE 33U
|
||||
#define SE_TIME_ZONE_PRIVILEGE 34U
|
||||
#define SE_CREATE_SYMBOLIC_LINK_PRIVILEGE 35U
|
||||
|
||||
#define SE_MAX_WELL_KNOWN_PRIVILEGE SE_CREATE_SYMBOLIC_LINK_PRIVILEGE
|
||||
|
||||
|
|
|
@ -3081,7 +3081,7 @@ mknod_worker (const char *path, mode_t type, mode_t mode, _major_t major,
|
|||
char buf[sizeof (":\\00000000:00000000:00000000") + PATH_MAX];
|
||||
sprintf (buf, ":\\%x:%x:%x", major, minor,
|
||||
type | (mode & (S_IRWXU | S_IRWXG | S_IRWXO)));
|
||||
return symlink_worker (buf, path, true, true);
|
||||
return symlink_worker (buf, path, true);
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
|
|
@ -243,8 +243,6 @@ extern "C" void vklog (int priority, const char *message, va_list ap);
|
|||
extern "C" void klog (int priority, const char *message, ...);
|
||||
bool child_copy (HANDLE, bool, ...);
|
||||
|
||||
int __reg3 symlink_worker (const char *, const char *, bool, bool);
|
||||
|
||||
class path_conv;
|
||||
|
||||
int __reg2 stat_worker (path_conv &pc, struct stat *buf);
|
||||
|
|
Loading…
Reference in New Issue