* 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:
Corinna Vinschen 2013-04-24 10:16:13 +00:00
parent bd91f4a96a
commit 9ecd475cd8
11 changed files with 246 additions and 92 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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}}}
};

View File

@ -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");

View File

@ -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 }
};

View File

@ -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; }

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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);