Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2017-07-24 18:33:20 +0300
committerCorinna Vinschen <corinna@vinschen.de>2017-07-24 18:33:20 +0300
commit3e80cefb16cab409c00d5b61be0f7a3befc688e3 (patch)
treed966684abb04e50270c240d9094826b5e13af8d9 /winsup/cygwin/fhandler_disk_file.cc
parent42f1be581cdc10438b797c3a5941035a97f01cc4 (diff)
cygwin: unify reparse point checking code into single function
So far we had two functions checking the content of a reparse point, readdir_check_reparse_point in fhandler_disk_file.cc for the sake of readdir, and symlink_info::check_reparse_point for the sake of generic path checking. * Rename check_reparse_point_target helper to check_reparse_point_string and convert to static function. * Create new check_reparse_point_target helper containing the core reparse point checking code * Just call check_reparse_point_target from readdir_check_reparse_point and symlink_info::check_reparse_point and only perform the unique task in those functions. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup/cygwin/fhandler_disk_file.cc')
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc67
1 files changed, 15 insertions, 52 deletions
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index 6cc081d98..2144a4cdc 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -161,62 +161,25 @@ path_conv::isgood_inode (ino_t ino) const
return true;
}
-/* Check reparse point to determine if it should be treated as a posix symlink
- or as a normal file/directory. Mount points are treated as normal directories
- to match behavior of other systems. Unknown reparse tags are used for
- things other than links (HSM, compression, dedup), and generally should be
- treated as a normal file/directory. Native symlinks and mount points are
- treated as posix symlinks, depending on the prefix of the target name.
- This logic needs to agree with equivalent logic in path.cc
- symlink_info::check_reparse_point() .
- */
+/* Check reparse point to determine if it should be treated as a
+ posix symlink or as a normal file/directory. Logic is explained
+ in detail in check_reparse_point_target in path.cc. */
static inline bool
readdir_check_reparse_point (POBJECT_ATTRIBUTES attr, bool remote)
{
- bool ret = false;
- IO_STATUS_BLOCK io;
+ NTSTATUS status;
HANDLE reph;
- UNICODE_STRING subst;
-
- if (NT_SUCCESS (NtOpenFile (&reph, READ_CONTROL, attr, &io,
- FILE_SHARE_VALID_FLAGS,
- FILE_OPEN_FOR_BACKUP_INTENT
- | FILE_OPEN_REPARSE_POINT)))
- {
- PREPARSE_DATA_BUFFER rp = (PREPARSE_DATA_BUFFER)
- alloca (MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
- if (NT_SUCCESS (NtFsControlFile (reph, NULL, NULL, NULL,
- &io, FSCTL_GET_REPARSE_POINT, NULL, 0,
- (LPVOID) rp, MAXIMUM_REPARSE_DATA_BUFFER_SIZE)))
- {
- /* If reparse point is stored on a remote volume, lstat returns
- them as normal files or dirs, not as symlink. For a description,
- see the comment preceeding remote check in
- symlink_info::check_reparse_point. */
- if (!remote && rp->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
- {
- RtlInitCountedUnicodeString (&subst,
- (WCHAR *)((char *)rp->MountPointReparseBuffer.PathBuffer
- + rp->MountPointReparseBuffer.SubstituteNameOffset),
- rp->MountPointReparseBuffer.SubstituteNameLength);
- if (check_reparse_point_target (&subst))
- ret = true;
- }
- else if (rp->ReparseTag == IO_REPARSE_TAG_SYMLINK)
- {
- if (rp->SymbolicLinkReparseBuffer.Flags & SYMLINK_FLAG_RELATIVE)
- ret = true;
- else
- {
- RtlInitCountedUnicodeString (&subst,
- (WCHAR *)((char *)rp->SymbolicLinkReparseBuffer.PathBuffer
- + rp->SymbolicLinkReparseBuffer.SubstituteNameOffset),
- rp->SymbolicLinkReparseBuffer.SubstituteNameLength);
- if (check_reparse_point_target (&subst))
- ret = true;
- }
- }
- }
+ IO_STATUS_BLOCK io;
+ tmp_pathbuf tp;
+ UNICODE_STRING symbuf;
+ bool ret = false;
+
+ status = NtOpenFile (&reph, READ_CONTROL, attr, &io, FILE_SHARE_VALID_FLAGS,
+ FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT);
+ if (NT_SUCCESS (status))
+ {
+ PREPARSE_DATA_BUFFER rp = (PREPARSE_DATA_BUFFER) tp.c_get ();
+ ret = (check_reparse_point_target (reph, remote, rp, &symbuf) > 0);
NtClose (reph);
}
return ret;