Fix various OS-related comments

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2015-12-15 21:43:33 +01:00
parent bb0fc7a2c0
commit 00e9bf2bb3
12 changed files with 68 additions and 93 deletions

View File

@ -207,17 +207,16 @@ enum fcwd_version_t {
FCWD_W8
};
/* This class is used to store the CWD starting with Windows Vista.
The CWD storage in the RTL_USER_PROCESS_PARAMETERS block is only
an afterthought now. The actual CWD storage is a FAST_CWD structure
which is allocated on the process heap. The new method only requires
minimal locking and it's much more multi-thread friendly. Presumably
it minimizes contention when accessing the CWD.
/* This class is used to store the CWD. The CWD storage in the
RTL_USER_PROCESS_PARAMETERS block is only an afterthought now. The actual
CWD storage is a FAST_CWD structure which is allocated on the process heap.
The new method only requires minimal locking and it's much more multi-thread
friendly. Presumably it minimizes contention when accessing the CWD.
The class fcwd_access_t is supposed to encapsulate the gory implementation
details depending on OS version from the calling functions.
The layout of all structures has been tested on 32 and 64 bit. */
class fcwd_access_t {
/* This is the layout used in Windows 8. */
/* This is the layout used in Windows 8 and later. */
struct FAST_CWD_8 {
LONG ReferenceCount; /* Only release when this is 0. */
HANDLE DirectoryHandle;

View File

@ -523,13 +523,12 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries)
We DONT_RESOLVE_DLL_REFERENCES at first in case the DLL lands in
the wrong spot;
NOTE: This step skips DLLs which loaded at their preferred
address in the parent because they should behave (we already
verified that their preferred address in the child is
available). However, this may fail on a Vista/Win7 machine with
ASLR active, because the ASLR base address will usually not equal
the preferred base recorded in the dll. In this case, we should
make the LoadLibraryExW call unconditional.
NOTE: This step skips DLLs which loaded at their preferred address in
the parent because they should behave (we already verified that their
preferred address in the child is available). However, this may fail
with ASLR active, because the ASLR base address will usually not equal
the preferred base recorded in the dll. In this case, we should make
the LoadLibraryExW call unconditional.
*/
for ( ; d; d = dlls.inext ())
if (d->handle != d->preferred_base)

View File

@ -304,8 +304,8 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
dev.parse (name);
else if (strcmp (name, ":sock:") == 0
/* NtQueryObject returns an error when called on an LSP socket
handle. While fdsock now tries to fetch the underlying
base socket, this only works on Vista and later. */
handle. fdsock tries to fetch the underlying base socket,
but this might fail. */
|| (strcmp (name, unknown_file) == 0
&& !::getsockopt ((SOCKET) handle, SOL_SOCKET, SO_RCVBUF,
(char *) &rcv, &len)))

View File

@ -1888,12 +1888,11 @@ fhandler_disk_file::opendir (int fd)
NFS clients hide dangling symlinks from directory queries,
unless you use the FileNamesInformation info class.
On newer NFS clients (>=Vista) FileIdBothDirectoryInformation
works fine, but only if the NFS share is mounted to a drive
letter. TODO: We don't test that here for now, but it might
be worth to test if there's a speed gain in using
FileIdBothDirectoryInformation, because it doesn't require to
open the file to read the inode number. */
FileIdBothDirectoryInformation works fine, but only if the NFS
share is mounted to a drive letter. TODO: We don't test that
here for now, but it might be worth to test if there's a speed
gain in using FileIdBothDirectoryInformation, because it doesn't
require to open the file to read the inode number. */
if (pc.hasgood_inode ())
{
dir->__flags |= dirent_set_d_ino;

View File

@ -38,11 +38,11 @@ eval_start_address ()
So we let the heap start at 0x6:00000000L. */
uintptr_t start_address = 0x600000000L;
#else
/* Starting with Vista, Windows performs heap ASLR. This spoils the entire
region below 0x20000000 for us, because that region is used by Windows
to randomize heap and stack addresses. Therefore we put our heap into a
safe region starting at 0x20000000. This should work right from the start
in 99% of the cases. */
/* Windows performs heap ASLR. This spoils the entire region below
0x20000000 for us, because that region is used by Windows to randomize
heap and stack addresses. Therefore we put our heap into a safe region
starting at 0x20000000. This should work right from the start in 99%
of the cases. */
uintptr_t start_address = 0x20000000L;
if ((uintptr_t) NtCurrentTeb () >= 0xbf000000L)
{

View File

@ -385,7 +385,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
and stuff like that. */
&& !is_mvfs (RtlEqualUnicodePathPrefix (&fsname, &ro_u_mvfs, FALSE))
/* NWFS == Novell Netware FS. Broken info class, see below. */
/* NcFsd == Novell Netware FS via own driver since Windows Vista. */
/* NcFsd == Novell Netware FS via own driver. */
&& !is_nwfs (RtlEqualUnicodeString (&fsname, &ro_u_nwfs, FALSE))
&& !is_ncfsd (RtlEqualUnicodeString (&fsname, &ro_u_ncfsd, FALSE))
/* UNIXFS == TotalNet Advanced Server (TAS). Doesn't support

View File

@ -608,7 +608,7 @@ fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc)
handle inheritance. An explanation for this weird behaviour would
be nice, though.
NOTE 2. Testing on x86_64 (XP, Vista, 2008 R2, W8) indicates that
NOTE 2. Testing on x86_64 (Vista, 2008 R2, W8) indicates that
this is no problem on 64 bit. So we set the default buffer size to
the default values in current 3.x Linux versions.
@ -1821,8 +1821,8 @@ get_adapters_addresses (PIP_ADAPTER_ADDRESSES *pa_ret, ULONG family)
DWORD ret;
gaa_wa param = { family, pa_ret };
if ((uintptr_t) &param >= (uintptr_t) 0x80000000L
&& wincap.has_gaa_largeaddress_bug ())
if (wincap.has_gaa_largeaddress_bug ()
&& (uintptr_t) &param >= (uintptr_t) 0x80000000L)
{
/* In Windows Vista and Windows 7 under WOW64, GetAdaptersAddresses fails
if it's running in a thread with a stack located in the large address
@ -3371,8 +3371,8 @@ cygwin_getaddrinfo (const char *hostname, const char *servname,
| AI_NUMERICSERV | AI_ADDRCONFIG | AI_V4MAPPED
| AI_IDN_MASK)))
return EAI_BADFLAGS;
/* AI_NUMERICSERV is not supported prior to Windows Vista. We just check
the servname parameter by ourselves here. */
/* AI_NUMERICSERV is not supported "by Microsoft providers". We just
check the servname parameter by ourselves here. */
if (hints && (hints->ai_flags & AI_NUMERICSERV))
{
char *p;

View File

@ -2889,9 +2889,7 @@ restart:
/* Reparse points are potentially symlinks. This check must be
performed before checking the SYSTEM attribute for sysfile
symlinks, since reparse points can have this flag set, too.
For instance, Vista starts to create a couple of reparse points
with SYSTEM and HIDDEN flags set. */
symlinks, since reparse points can have this flag set, too. */
if ((fileattr & FILE_ATTRIBUTE_REPARSE_POINT))
{
res = check_reparse_point (h, fs.is_remote_drive ());
@ -3974,13 +3972,9 @@ fcwd_access_t::SetVersionFromPointer (PBYTE buf_p, bool is_buffer)
}
/* This function scans the code in ntdll.dll to find the address of the
global variable used to access the CWD starting with Vista. While the
pointer is global, it's not exported from the DLL, unfortunately.
Therefore we have to use some knowledge to figure out the address.
This code has been tested on Vista 32/64 bit, Server 2008 32/64 bit,
Windows 7 32/64 bit, Server 2008 R2 (which is only 64 bit anyway),
Windows 8 32/64 bit, Windows 8.1 32/64 bit, and Server 2012 R2. */
global variable used to access the CWD. While the pointer is global,
it's not exported from the DLL, unfortunately. Therefore we have to
use some knowledge to figure out the address. */
#ifdef __x86_64__
@ -4240,9 +4234,8 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count)
fast_cwd_ptr = find_fast_cwd ();
if (fast_cwd_ptr)
{
/* Default method starting with Vista. If we got a valid value for
fast_cwd_ptr, we can simply replace the RtlSetCurrentDirectory_U
function entirely, just as on pre-Vista. */
/* If we got a valid value for fast_cwd_ptr, we can simply replace
the RtlSetCurrentDirectory_U function entirely. */
PVOID heap = peb.ProcessHeap;
/* First allocate a new fcwd_access_t structure on the heap.
The new fcwd_access_t structure is 4 byte bigger than the old one,
@ -4274,14 +4267,13 @@ cwdstuff::override_win32_cwd (bool init, ULONG old_dismount_count)
}
else
{
/* This is more a hack, and it's only used on Vista and later if we
failed to find the fast_cwd_ptr value. What we do here is to call
RtlSetCurrentDirectory_U and let it set up a new FAST_CWD
structure. Afterwards, compute the address of that structure
utilizing the fact that the buffer address in the user process
parameter block is actually pointing to the buffer in that
FAST_CWD structure. Then replace the directory handle in that
structure with our own handle and close the original one.
/* This is more a hack, and it's only used if we failed to find the
fast_cwd_ptr value. We call RtlSetCurrentDirectory_U and let it
set up a new FAST_CWD structure. Afterwards, compute the address
of that structure utilizing the fact that the buffer address in
the user process parameter block is actually pointing to the buffer
in that FAST_CWD structure. Then replace the directory handle in
that structure with our own handle and close the original one.
Note that the call to RtlSetCurrentDirectory_U also closes our
old dir handle, so there won't be any handle left open.
@ -4374,13 +4366,6 @@ cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd)
- SetCurrentDirectory can naturally not work on virtual Cygwin paths
like /proc or /cygdrive.
Unfortunately, even though we have access to the Win32 process parameter
block, we can't just replace the directory handle. Starting with Vista,
the handle is used elsewhere, and just replacing the handle in the process
parameter block shows quite surprising results.
FIXME: If we ever find a *safe* way to replace the directory handle in
the process parameter block, we're back in business.
Nevertheless, doing entirely without SetCurrentDirectory is not really
feasible, because it breaks too many mixed applications using the Win32
API.
@ -4401,11 +4386,11 @@ cwdstuff::set (path_conv *nat_cwd, const char *posix_cwd)
}
/* Memorize old DismountCount before opening the dir. This value is
stored in the FAST_CWD structure on Vista and later. It would be
simpler to fetch the old DismountCount in override_win32_cwd, but
Windows also fetches it before opening the directory handle. It's
not quite clear if that's really required, but since we don't know
the side effects of this action, we better follow Windows' lead. */
stored in the FAST_CWD structure. It would be simpler to fetch the
old DismountCount in override_win32_cwd, but Windows also fetches
it before opening the directory handle. It's not quite clear if
that's really required, but since we don't know the side effects of
this action, we better follow Windows' lead. */
ULONG old_dismount_count = SharedUserData.DismountCount;
/* Open a directory handle with FILE_OPEN_FOR_BACKUP_INTENT and with all
sharing flags set. The handle is right now used in exceptions.cc only,

View File

@ -36,12 +36,11 @@ issetugid (void)
return cygheap->user.issetuid () ? 1 : 0;
}
/* Starting with Windows Vista, the token returned by system functions
is a restricted token. The full admin token is linked to it and can
be fetched with NtQueryInformationToken. This function returns the original
token on pre-Vista, and the elevated token on Vista++ if it's available,
the original token otherwise. The token handle is also made inheritable
since that's necessary anyway. */
/* The token returned by system functions is a restricted token. The full
admin token is linked to it and can be fetched with NtQueryInformationToken.
This function returns the elevated token if available, the original token
otherwise. The token handle is also made inheritable since that's necessary
anyway. */
static HANDLE
get_full_privileged_inheritable_token (HANDLE token)
{
@ -219,7 +218,7 @@ get_user_profile_directory (PCWSTR sidstr, PWCHAR path, SIZE_T path_len)
}
/* Load user profile if it's not already loaded. If the user profile doesn't
exist on the machine, and if we're running Vista or later, try to create it.
exist on the machine try to create it.
Return a handle to the loaded user registry hive only if it got actually
loaded here, not if it already existed. There's no reliable way to know
@ -821,8 +820,8 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern)
/* Check that all groups in the setgroups () list are in the token.
A token created through ADVAPI should be allowed to contain more
groups than requested through setgroups(), especially since Vista
and the addition of integrity groups. */
groups than requested through setgroups(), especially since the
addition of integrity groups. */
memset (saw, 0, sizeof(saw));
for (int gidx = 0; gidx < groups.sgsids.count (); gidx++)
{

View File

@ -628,11 +628,6 @@ _recycler_sd (void *buf, bool users, bool dir)
return NULL;
RtlCreateSecurityDescriptor (psd, SECURITY_DESCRIPTOR_REVISION);
PACL dacl = (PACL) (psd + 1);
/* Pre-Vista, the per-user recycler dir has a rather too complicated
ACL by default, which has distinct ACEs for inheritable and non-inheritable
permissions. However, this ACL is practically equivalent to the ACL
created since Vista. Therefore we simplify our job here and create the
pre-Vista permissions the same way as on Vista and later. */
RtlCreateAcl (dacl, MAX_DACL_LEN (3), ACL_REVISION);
RtlAddAccessAllowedAceEx (dacl, ACL_REVISION,
dir ? SUB_CONTAINERS_AND_OBJECTS_INHERIT

View File

@ -89,7 +89,6 @@ void uinfo_init ();
#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 31U
#define SE_RELABEL_PRIVILEGE 32U
#define SE_INCREASE_WORKING_SET_PRIVILEGE 33U

View File

@ -268,11 +268,11 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access, ULONG flags)
them into the recycler. */
if (pfni->FileNameLength == 2) /* root dir. */
goto out;
/* The recycler name on Vista and later is $Recycler.Bin by default. If the
recycler dir disappeared for some reason, the shell32.dll recreates the
directory in all upper case. So, we never know beforehand if the dir
is written in mixed case or in all upper case. That's a problem when
using casesensitivity. If the file handle given to FileRenameInformation
/* The recycler name is $Recycler.Bin by default. If the recycler dir
disappeared for some reason, the shell32.dll recreates the directory in
all upper case. So, we never know beforehand if the dir is written in
mixed case or in all upper case. That's a problem when using
casesensitivity. If the file handle given to FileRenameInformation
has been opened casesensitive, the call also handles the path to the
target dir casesensitive. Rather then trying to find the right name
of the recycler, we just reopen the file to move with OBJ_CASE_INSENSITIVE,
@ -958,10 +958,10 @@ try_again:
"Subsequently, the only legal operation by such a caller is
to close the open file handle."
FIXME? On Vista and later, we could use FILE_HARD_LINK_INFORMATION
to find all hardlinks and use one of them to restore the R/O bit,
after the NtClose, but before we stop the transaction. This
avoids the aforementioned problem entirely . */
FIXME? We could use FILE_HARD_LINK_INFORMATION to find all
hardlinks and use one of them to restore the R/O bit, after the
NtClose, but before we stop the transaction. This avoids the
aforementioned problem entirely . */
else if (pc.is_lnk_symlink () && num_links > 1)
NtSetAttributesFile (fh, pc.file_attributes ());
}
@ -3219,9 +3219,9 @@ seteuid32 (uid_t uid)
CW_TOKEN_RESTRICTED);
setuid (getuid ());
Note that using the current uid is a requirement! Starting with Windows
Vista, we have restricted tokens galore (UAC), so this is really just
a special case to restict your own processes to lesser rights. */
Note that using the current uid is a requirement! We have restricted
tokens galore (UAC), so this is really just a special case to restrict
your own processes to lesser rights. */
bool request_restricted_uid_switch = (uid == myself->uid
&& cygheap->user.ext_token_is_restricted);
if (uid == myself->uid && !cygheap->user.groups.ischanged