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
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2006-12-10 15:56:50 +0300
committerCorinna Vinschen <corinna@vinschen.de>2006-12-10 15:56:50 +0300
commit30cf835f7e12552bac12eb1cd9123febe909d6e2 (patch)
tree782fde972ea8e50064224e8c56b50602732db756 /winsup
parent8af19fdb2507b08e0b3c96068502a41e419ee402 (diff)
* fhandler.cc (rootdir): Drop useless post-increment. Take volume
mount points into account. (check_posix_perm): Allocate space for root directory big enough.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog6
-rw-r--r--winsup/cygwin/fhandler.cc58
2 files changed, 62 insertions, 2 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 2be62f2f3..d9faceb85 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,9 @@
+2006-12-10 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.cc (rootdir): Drop useless post-increment. Take volume
+ mount points into account.
+ (check_posix_perm): Allocate space for root directory big enough.
+
2006-12-09 Corinna Vinschen <corinna@vinschen.de>
* syscalls.cc (try_to_bin): Add comment that this is not possibly
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 0fc9e6fcc..03dc0b803 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -1221,7 +1221,7 @@ rootdir (const char *full_path, char *root_path)
if (full_path[1] == ':')
{
- *rootp++ = *full_path++;
+ *rootp++ = *full_path;
*rootp++ = ':';
}
else if (full_path[0] == '\\' && full_path[1] == '\\')
@@ -1239,6 +1239,60 @@ rootdir (const char *full_path, char *root_path)
*rootp++ = '\\';
*rootp = '\0';
+
+ /* This also determines whether reparse points are available. */
+ if (!wincap.has_guid_volumes ())
+ return root_path;
+
+ PREPARSE_DATA_BUFFER rp = (PREPARSE_DATA_BUFFER)
+ alloca (MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
+
+ char *test_path = (char *) alloca (CYG_MAX_PATH);
+ strcpy (test_path, full_path);
+
+ /* This determines the minimum length of the path we test for mount points.
+ If we're below this value, it's the root dir of the path itself. */
+ char *min_c = test_path + (rootp - root_path);
+ char *c = min_c;
+ while (*c)
+ ++c;
+ while (c > min_c)
+ {
+ *c = '\0';
+
+# define MOUNTPT_ATTR (FILE_ATTRIBUTE_DIRECTORY \
+ | FILE_ATTRIBUTE_REPARSE_POINT)
+ DWORD attr = GetFileAttributes (test_path);
+ if (attr != INVALID_FILE_ATTRIBUTES
+ && (attr & MOUNTPT_ATTR) == MOUNTPT_ATTR)
+ {
+ HANDLE h = CreateFile (test_path, GENERIC_READ, FILE_SHARE_READ,
+ &sec_none_nih, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT
+ | FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ DWORD size;
+ BOOL ret = DeviceIoControl (h, FSCTL_GET_REPARSE_POINT, NULL,
+ 0, (LPVOID) rp,
+ MAXIMUM_REPARSE_DATA_BUFFER_SIZE,
+ &size, NULL);
+ CloseHandle (h);
+ if (ret
+ && rp->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT
+ && !rp->SymbolicLinkReparseBuffer.PrintNameLength)
+ {
+ memcpy (root_path, test_path, len = c - test_path);
+ strcpy (root_path + len, "\\");
+ CloseHandle (h);
+ break;
+ }
+ }
+ }
+ while (--c > min_c && *c != '\\')
+ ;
+ }
+
return root_path;
}
@@ -1739,7 +1793,7 @@ check_posix_perm (const char *fname, int v)
if (!allow_ntsec)
return 0;
- char *root = rootdir (fname, (char *)alloca (strlen (fname)));
+ char *root = rootdir (fname, (char *)alloca (strlen (fname) + 2));
if (!allow_smbntsec
&& ((root[0] == '\\' && root[1] == '\\')