(smb_extended_info): Move here from path.cc.
(fs_info::update): Ditto.
(mount_info::create_root_entry): Delay conversion to slashes and use passed in
buffer to figure out fs type.
* path.cc (smb_extended_info): Move.
(fs_info::update): Ditto.
* mount.h: New file. Move mount information here.
* path.h: (fs_info::update): Move.
* shared_info.h (mount_item): Ditto.
+2008-12-25 Christopher Faylor <me+cygwin@cgf.cx>
+
+ * mount.cc: Change comment.
+ (smb_extended_info): Move here from path.cc.
+ (fs_info::update): Ditto.
+ (mount_info::create_root_entry): Delay conversion to slashes and use
+ passed in buffer to figure out fs type.
+ * path.cc (smb_extended_info): Move.
+ (fs_info::update): Ditto.
+ * mount.h: New file. Move mount information here.
+ * path.h: (fs_info::update): Move.
+ * shared_info.h (mount_item): Ditto.
+
2008-12-24 Christopher Faylor <me+cygwin@cgf.cx>
* path.cc (symlink_info::check_shortcut): Ensure that symlink handle is
-/* path.cc: path support.
+/* mount.cc: mount handling.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008 Red Hat, Inc.
#include "miscfuncs.h"
#include <mntent.h>
#include <ctype.h>
+#include <winioctl.h>
#include <wingdi.h>
#include <winuser.h>
#include <winnetwk.h>
#include "cygerrno.h"
#include "security.h"
#include "path.h"
+#include "shared_info.h"
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"
-#include "shared_info.h"
#include "cygtls.h"
#include "tls_pbuf.h"
#include <ntdll.h>
return true;
}
+/* Beginning with Samba 3.0.28a, Samba allows to get version information using
+ the ExtendedInfo member returned by a FileFsObjectIdInformation request.
+ We just store the samba_version information for now. Older versions than
+ 3.2 are still guessed at by testing the file system flags. */
+#define SAMBA_EXTENDED_INFO_MAGIC 0x536d4261 /* "SmBa" */
+#define SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH 28
+#pragma pack(push,4)
+struct smb_extended_info {
+ DWORD samba_magic; /* Always SAMBA_EXTENDED_INFO_MAGIC */
+ DWORD samba_version; /* Major/Minor/Release/Revision */
+ DWORD samba_subversion; /* Prerelease/RC/Vendor patch */
+ LARGE_INTEGER samba_gitcommitdate;
+ char samba_version_string[SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH];
+};
+#pragma pack(pop)
+
+bool
+fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
+{
+ NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND;
+ HANDLE vol;
+ OBJECT_ATTRIBUTES attr;
+ IO_STATUS_BLOCK io;
+ bool no_media = false;
+ FILE_FS_DEVICE_INFORMATION ffdi;
+ FILE_FS_OBJECTID_INFORMATION ffoi;
+ struct {
+ FILE_FS_ATTRIBUTE_INFORMATION ffai;
+ WCHAR buf[NAME_MAX + 1];
+ } ffai_buf;
+ struct {
+ FILE_FS_VOLUME_INFORMATION ffvi;
+ WCHAR buf[NAME_MAX + 1];
+ } ffvi_buf;
+ UNICODE_STRING fsname, testname;
+
+ clear ();
+ if (in_vol)
+ vol = in_vol;
+ else
+ {
+ /* Always caseinsensitive. We really just need access to the drive. */
+ InitializeObjectAttributes (&attr, upath, OBJ_CASE_INSENSITIVE, NULL,
+ NULL);
+ status = NtOpenFile (&vol, READ_CONTROL, &attr, &io,
+ FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
+ while (!NT_SUCCESS (status)
+ && (attr.ObjectName->Length > 7 * sizeof (WCHAR)
+ || status == STATUS_NO_MEDIA_IN_DEVICE))
+ {
+ UNICODE_STRING dir;
+ RtlSplitUnicodePath (attr.ObjectName, &dir, NULL);
+ attr.ObjectName = &dir;
+ if (status == STATUS_NO_MEDIA_IN_DEVICE)
+ {
+ no_media = true;
+ dir.Length = 6 * sizeof (WCHAR);
+ }
+ else if (dir.Length > 7 * sizeof (WCHAR))
+ dir.Length -= sizeof (WCHAR);
+ status = NtOpenFile (&vol, READ_CONTROL, &attr, &io,
+ FILE_SHARE_VALID_FLAGS,
+ FILE_OPEN_FOR_BACKUP_INTENT);
+ }
+ if (!NT_SUCCESS (status))
+ {
+ debug_printf ("Cannot access path %S, status %08lx",
+ attr.ObjectName, status);
+ NtClose (vol);
+ return false;
+ }
+ }
+
+ status = NtQueryVolumeInformationFile (vol, &io, &ffvi_buf.ffvi,
+ sizeof ffvi_buf,
+ FileFsVolumeInformation);
+ sernum = NT_SUCCESS (status) ? ffvi_buf.ffvi.VolumeSerialNumber : 0;
+ status = NtQueryVolumeInformationFile (vol, &io, &ffdi, sizeof ffdi,
+ FileFsDeviceInformation);
+ if (!NT_SUCCESS (status))
+ ffdi.DeviceType = ffdi.Characteristics = 0;
+
+ if (ffdi.Characteristics & FILE_REMOTE_DEVICE
+ || (!ffdi.DeviceType
+ && RtlEqualUnicodePathPrefix (attr.ObjectName, L"\\??\\UNC\\", TRUE)))
+ is_remote_drive (true);
+ else
+ is_remote_drive (false);
+
+ if (!no_media)
+ status = NtQueryVolumeInformationFile (vol, &io, &ffai_buf.ffai,
+ sizeof ffai_buf,
+ FileFsAttributeInformation);
+ if (no_media || !NT_SUCCESS (status))
+ {
+ debug_printf ("Cannot get volume attributes (%S), %08lx",
+ attr.ObjectName, status);
+ if (!in_vol)
+ NtClose (vol);
+ return false;
+ }
+ flags (ffai_buf.ffai.FileSystemAttributes);
+ name_len (ffai_buf.ffai.MaximumComponentNameLength);
+/* 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
+ capabilities and to ignore flags indicating a specific state of this
+ volume. At present these flags to ignore are FILE_VOLUME_IS_COMPRESSED
+ and FILE_READ_ONLY_VOLUME. */
+#define GETVOLINFO_VALID_MASK (0x003701ffUL)
+#define TEST_GVI(f,m) (((f) & GETVOLINFO_VALID_MASK) == (m))
+
+/* Volume quotas are potentially supported since Samba 3.0, object ids and
+ the unicode on disk flag since Samba 3.2. */
+#define SAMBA_IGNORE (FILE_VOLUME_QUOTAS \
+ | FILE_SUPPORTS_OBJECT_IDS \
+ | FILE_UNICODE_ON_DISK)
+#define FS_IS_SAMBA TEST_GVI(flags () & ~SAMBA_IGNORE, \
+ FILE_CASE_SENSITIVE_SEARCH \
+ | FILE_CASE_PRESERVED_NAMES \
+ | FILE_PERSISTENT_ACLS)
+#define FS_IS_NETAPP_DATAONTAP TEST_GVI(flags (), \
+ FILE_CASE_SENSITIVE_SEARCH \
+ | FILE_CASE_PRESERVED_NAMES \
+ | FILE_UNICODE_ON_DISK \
+ | FILE_PERSISTENT_ACLS \
+ | FILE_NAMED_STREAMS)
+ RtlInitCountedUnicodeString (&fsname, ffai_buf.ffai.FileSystemName,
+ ffai_buf.ffai.FileSystemNameLength);
+ is_fat (RtlEqualUnicodePathPrefix (&fsname, L"FAT", TRUE));
+ RtlInitUnicodeString (&testname, L"NTFS");
+ if (is_remote_drive ())
+ {
+ /* This always fails on NT4. */
+ status = NtQueryVolumeInformationFile (vol, &io, &ffoi, sizeof ffoi,
+ FileFsObjectIdInformation);
+ if (NT_SUCCESS (status))
+ {
+ smb_extended_info *extended_info = (smb_extended_info *)
+ &ffoi.ExtendedInfo;
+ if (extended_info->samba_magic == SAMBA_EXTENDED_INFO_MAGIC)
+ {
+ is_samba (true);
+ samba_version (extended_info->samba_version);
+ }
+ }
+ /* Test for Samba on NT4 or for older Samba releases not supporting
+ extended info. */
+ if (!is_samba ())
+ is_samba (RtlEqualUnicodeString (&fsname, &testname, FALSE)
+ && FS_IS_SAMBA);
+
+ if (!is_samba ())
+ {
+ is_netapp (RtlEqualUnicodeString (&fsname, &testname, FALSE)
+ && FS_IS_NETAPP_DATAONTAP);
+
+ RtlInitUnicodeString (&testname, L"NFS");
+ is_nfs (RtlEqualUnicodeString (&fsname, &testname, FALSE));
+
+ if (!is_nfs ())
+ {
+ /* Known remote file systems which can't handle calls to
+ NtQueryDirectoryFile(FileIdBothDirectoryInformation) */
+ RtlInitUnicodeString (&testname, L"UNIXFS");
+ has_buggy_fileid_dirinfo (RtlEqualUnicodeString (&fsname,
+ &testname,
+ FALSE));
+
+ /* Known remote file systems with buggy open calls. Further
+ explanation in fhandler.cc (fhandler_disk_file::open). */
+ RtlInitUnicodeString (&testname, L"SUNWNFS");
+ has_buggy_open (RtlEqualUnicodeString (&fsname, &testname,
+ FALSE));
+ }
+ }
+ }
+ is_ntfs (RtlEqualUnicodeString (&fsname, &testname, FALSE)
+ && !is_samba () && !is_netapp ());
+ is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM);
+
+ has_acls (flags () & FS_PERSISTENT_ACLS);
+ hasgood_inode (((flags () & FILE_PERSISTENT_ACLS) && !is_netapp ())
+ || is_nfs ());
+ /* Case sensitivity is supported if FILE_CASE_SENSITIVE_SEARCH is set,
+ except on Samba which handles Windows clients case insensitive.
+ NFS doesn't set the FILE_CASE_SENSITIVE_SEARCH flag but is case
+ sensitive. */
+ caseinsensitive ((!(flags () & FILE_CASE_SENSITIVE_SEARCH) || is_samba ())
+ && !is_nfs ());
+
+ if (!in_vol)
+ NtClose (vol);
+ return true;
+}
+
inline void
mount_info::create_root_entry (const PWCHAR root)
{
table because the mount table might change, causing weird effects
from the getmntent user's point of view. */
- slashify (native_path, _my_tls.locals.mnt_fsname, false);
ret.mnt_fsname = _my_tls.locals.mnt_fsname;
strcpy (_my_tls.locals.mnt_dir, posix_path);
ret.mnt_dir = _my_tls.locals.mnt_dir;
tmp_pathbuf tp;
UNICODE_STRING unat;
tp.u_get (&unat);
- get_nt_native_path (_my_tls.locals.mnt_fsname, unat);
+ get_nt_native_path (native_path, unat);
if (append_bs)
RtlAppendUnicodeToString (&unat, L"\\");
mntinfo.update (&unat, NULL);
ret.mnt_type = _my_tls.locals.mnt_type;
+ slashify (native_path, _my_tls.locals.mnt_fsname, false);
+
/* mnt_opts is a string that details mount params such as
binary or textmode, or exec. We don't print
`silent' here; it's a magic internal thing. */
--- /dev/null
+/* mount.h: mount definitions.
+
+ Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
+ 2006, 2007, 2008 Red Hat, Inc.
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#ifndef _MOUNT_H
+#define _MOUNT_H
+
+class fs_info
+{
+ struct status_flags
+ {
+ ULONG flags; /* Volume flags */
+ ULONG samba_version; /* Samba version if available */
+ ULONG name_len; /* MaximumComponentNameLength */
+ unsigned is_remote_drive : 1;
+ unsigned has_buggy_open : 1;
+ unsigned has_buggy_fileid_dirinfo : 1;
+ unsigned has_acls : 1;
+ unsigned hasgood_inode : 1;
+ unsigned caseinsensitive : 1;
+ unsigned is_fat : 1;
+ unsigned is_ntfs : 1;
+ unsigned is_samba : 1;
+ unsigned is_nfs : 1;
+ unsigned is_netapp : 1;
+ unsigned is_cdrom : 1;
+ } status;
+ ULONG sernum;
+ public:
+ void clear () { memset (&status, 0 , sizeof status); sernum = 0UL; }
+ fs_info () { clear (); }
+
+ IMPLEMENT_STATUS_FLAG (ULONG, flags)
+ IMPLEMENT_STATUS_FLAG (ULONG, samba_version)
+ IMPLEMENT_STATUS_FLAG (ULONG, name_len)
+ IMPLEMENT_STATUS_FLAG (bool, is_remote_drive)
+ IMPLEMENT_STATUS_FLAG (bool, has_buggy_open)
+ IMPLEMENT_STATUS_FLAG (bool, has_buggy_fileid_dirinfo)
+ IMPLEMENT_STATUS_FLAG (bool, has_acls)
+ IMPLEMENT_STATUS_FLAG (bool, hasgood_inode)
+ IMPLEMENT_STATUS_FLAG (bool, caseinsensitive)
+ IMPLEMENT_STATUS_FLAG (bool, is_fat)
+ IMPLEMENT_STATUS_FLAG (bool, is_ntfs)
+ IMPLEMENT_STATUS_FLAG (bool, is_samba)
+ IMPLEMENT_STATUS_FLAG (bool, is_nfs)
+ IMPLEMENT_STATUS_FLAG (bool, is_netapp)
+ IMPLEMENT_STATUS_FLAG (bool, is_cdrom)
+ ULONG serial_number () const { return sernum; }
+
+ bool update (PUNICODE_STRING, HANDLE) __attribute__ ((regparm (3)));
+};
+
+/* Mount table entry */
+
+class mount_item
+{
+ public:
+ /* FIXME: Nasty static allocation. Need to have a heap in the shared
+ area [with the user being able to configure at runtime the max size]. */
+ /* Win32-style mounted partition source ("C:\foo\bar").
+ native_path[0] == 0 for unused entries. */
+ char native_path[CYG_MAX_PATH];
+ int native_pathlen;
+
+ /* POSIX-style mount point ("/foo/bar") */
+ char posix_path[CYG_MAX_PATH];
+ int posix_pathlen;
+
+ unsigned flags;
+
+ void init (const char *dev, const char *path, unsigned flags);
+
+ struct mntent *getmntent ();
+ int build_win32 (char *, const char *, unsigned *, unsigned);
+};
+
+/* Warning: Decreasing this value will cause cygwin.dll to ignore existing
+ higher numbered registry entries. Don't change this number willy-nilly.
+ What we need is to have a more dynamic allocation scheme, but the current
+ scheme should be satisfactory for a long while yet. */
+#define MAX_MOUNTS 30
+
+#define USER_VERSION 1 // increment when mount table changes and
+#define USER_VERSION_MAGIC CYGWIN_VERSION_MAGIC (USER_MAGIC, USER_VERSION)
+#define CURR_USER_MAGIC 0xb2232e71U
+
+class reg_key;
+struct device;
+
+/* NOTE: Do not make gratuitous changes to the names or organization of the
+ below class. The layout is checksummed to determine compatibility between
+ different cygwin versions. */
+class mount_info
+{
+ public:
+ DWORD sys_mount_table_counter;
+ int nmounts;
+ mount_item mount[MAX_MOUNTS];
+
+ /* cygdrive_prefix is used as the root of the path automatically
+ prepended to a path when the path has no associated mount.
+ cygdrive_flags are the default flags for the cygdrives. */
+ char cygdrive[CYG_MAX_PATH];
+ size_t cygdrive_len;
+ unsigned cygdrive_flags;
+ private:
+ int posix_sorted[MAX_MOUNTS];
+ int native_sorted[MAX_MOUNTS];
+
+ public:
+ void init ();
+ int add_item (const char *dev, const char *path, unsigned flags);
+ int del_item (const char *path, unsigned flags);
+
+ unsigned set_flags_from_win32_path (const char *path);
+ int conv_to_win32_path (const char *src_path, char *dst, device&,
+ unsigned *flags = NULL);
+ int conv_to_posix_path (PWCHAR src_path, char *posix_path,
+ int keep_rel_p);
+ int conv_to_posix_path (const char *src_path, char *posix_path,
+ int keep_rel_p);
+ struct mntent *getmntent (int x);
+
+ int write_cygdrive_info (const char *cygdrive_prefix, unsigned flags);
+ int get_cygdrive_info (char *user, char *system, char* user_flags,
+ char* system_flags);
+ void cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p);
+ int get_mounts_here (const char *parent_dir, int,
+ PUNICODE_STRING mount_points,
+ PUNICODE_STRING cygd);
+
+ private:
+ void sort ();
+ void mount_slash ();
+ void create_root_entry (const PWCHAR root);
+
+ bool from_fstab_line (char *line, bool user);
+ bool from_fstab (bool user, WCHAR [], PWCHAR);
+
+ int cygdrive_win32_path (const char *src, char *dst, int& unit);
+};
+#endif
strcpy (path, ".");
}
-/* Beginning with Samba 3.0.28a, Samba allows to get version information using
- the ExtendedInfo member returned by a FileFsObjectIdInformation request.
- We just store the samba_version information for now. Older versions than
- 3.2 are still guessed at by testing the file system flags. */
-#define SAMBA_EXTENDED_INFO_MAGIC 0x536d4261 /* "SmBa" */
-#define SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH 28
-#pragma pack(push,4)
-struct smb_extended_info {
- DWORD samba_magic; /* Always SAMBA_EXTENDED_INFO_MAGIC */
- DWORD samba_version; /* Major/Minor/Release/Revision */
- DWORD samba_subversion; /* Prerelease/RC/Vendor patch */
- LARGE_INTEGER samba_gitcommitdate;
- char samba_version_string[SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH];
-};
-#pragma pack(pop)
-
-bool
-fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
-{
- NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND;
- HANDLE vol;
- OBJECT_ATTRIBUTES attr;
- IO_STATUS_BLOCK io;
- bool no_media = false;
- FILE_FS_DEVICE_INFORMATION ffdi;
- FILE_FS_OBJECTID_INFORMATION ffoi;
- struct {
- FILE_FS_ATTRIBUTE_INFORMATION ffai;
- WCHAR buf[NAME_MAX + 1];
- } ffai_buf;
- struct {
- FILE_FS_VOLUME_INFORMATION ffvi;
- WCHAR buf[NAME_MAX + 1];
- } ffvi_buf;
- UNICODE_STRING fsname, testname;
-
- clear ();
- if (in_vol)
- vol = in_vol;
- else
- {
- /* Always caseinsensitive. We really just need access to the drive. */
- InitializeObjectAttributes (&attr, upath, OBJ_CASE_INSENSITIVE, NULL,
- NULL);
- status = NtOpenFile (&vol, READ_CONTROL, &attr, &io,
- FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
- while (!NT_SUCCESS (status)
- && (attr.ObjectName->Length > 7 * sizeof (WCHAR)
- || status == STATUS_NO_MEDIA_IN_DEVICE))
- {
- UNICODE_STRING dir;
- RtlSplitUnicodePath (attr.ObjectName, &dir, NULL);
- attr.ObjectName = &dir;
- if (status == STATUS_NO_MEDIA_IN_DEVICE)
- {
- no_media = true;
- dir.Length = 6 * sizeof (WCHAR);
- }
- else if (dir.Length > 7 * sizeof (WCHAR))
- dir.Length -= sizeof (WCHAR);
- status = NtOpenFile (&vol, READ_CONTROL, &attr, &io,
- FILE_SHARE_VALID_FLAGS,
- FILE_OPEN_FOR_BACKUP_INTENT);
- }
- if (!NT_SUCCESS (status))
- {
- debug_printf ("Cannot access path %S, status %08lx",
- attr.ObjectName, status);
- NtClose (vol);
- return false;
- }
- }
-
- status = NtQueryVolumeInformationFile (vol, &io, &ffvi_buf.ffvi,
- sizeof ffvi_buf,
- FileFsVolumeInformation);
- sernum = NT_SUCCESS (status) ? ffvi_buf.ffvi.VolumeSerialNumber : 0;
- status = NtQueryVolumeInformationFile (vol, &io, &ffdi, sizeof ffdi,
- FileFsDeviceInformation);
- if (!NT_SUCCESS (status))
- ffdi.DeviceType = ffdi.Characteristics = 0;
-
- if (ffdi.Characteristics & FILE_REMOTE_DEVICE
- || (!ffdi.DeviceType
- && RtlEqualUnicodePathPrefix (attr.ObjectName, L"\\??\\UNC\\", TRUE)))
- is_remote_drive (true);
- else
- is_remote_drive (false);
-
- if (!no_media)
- status = NtQueryVolumeInformationFile (vol, &io, &ffai_buf.ffai,
- sizeof ffai_buf,
- FileFsAttributeInformation);
- if (no_media || !NT_SUCCESS (status))
- {
- debug_printf ("Cannot get volume attributes (%S), %08lx",
- attr.ObjectName, status);
- if (!in_vol)
- NtClose (vol);
- return false;
- }
- flags (ffai_buf.ffai.FileSystemAttributes);
- name_len (ffai_buf.ffai.MaximumComponentNameLength);
-/* 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
- capabilities and to ignore flags indicating a specific state of this
- volume. At present these flags to ignore are FILE_VOLUME_IS_COMPRESSED
- and FILE_READ_ONLY_VOLUME. */
-#define GETVOLINFO_VALID_MASK (0x003701ffUL)
-#define TEST_GVI(f,m) (((f) & GETVOLINFO_VALID_MASK) == (m))
-
-/* Volume quotas are potentially supported since Samba 3.0, object ids and
- the unicode on disk flag since Samba 3.2. */
-#define SAMBA_IGNORE (FILE_VOLUME_QUOTAS \
- | FILE_SUPPORTS_OBJECT_IDS \
- | FILE_UNICODE_ON_DISK)
-#define FS_IS_SAMBA TEST_GVI(flags () & ~SAMBA_IGNORE, \
- FILE_CASE_SENSITIVE_SEARCH \
- | FILE_CASE_PRESERVED_NAMES \
- | FILE_PERSISTENT_ACLS)
-#define FS_IS_NETAPP_DATAONTAP TEST_GVI(flags (), \
- FILE_CASE_SENSITIVE_SEARCH \
- | FILE_CASE_PRESERVED_NAMES \
- | FILE_UNICODE_ON_DISK \
- | FILE_PERSISTENT_ACLS \
- | FILE_NAMED_STREAMS)
- RtlInitCountedUnicodeString (&fsname, ffai_buf.ffai.FileSystemName,
- ffai_buf.ffai.FileSystemNameLength);
- is_fat (RtlEqualUnicodePathPrefix (&fsname, L"FAT", TRUE));
- RtlInitUnicodeString (&testname, L"NTFS");
- if (is_remote_drive ())
- {
- /* This always fails on NT4. */
- status = NtQueryVolumeInformationFile (vol, &io, &ffoi, sizeof ffoi,
- FileFsObjectIdInformation);
- if (NT_SUCCESS (status))
- {
- smb_extended_info *extended_info = (smb_extended_info *)
- &ffoi.ExtendedInfo;
- if (extended_info->samba_magic == SAMBA_EXTENDED_INFO_MAGIC)
- {
- is_samba (true);
- samba_version (extended_info->samba_version);
- }
- }
- /* Test for Samba on NT4 or for older Samba releases not supporting
- extended info. */
- if (!is_samba ())
- is_samba (RtlEqualUnicodeString (&fsname, &testname, FALSE)
- && FS_IS_SAMBA);
-
- if (!is_samba ())
- {
- is_netapp (RtlEqualUnicodeString (&fsname, &testname, FALSE)
- && FS_IS_NETAPP_DATAONTAP);
-
- RtlInitUnicodeString (&testname, L"NFS");
- is_nfs (RtlEqualUnicodeString (&fsname, &testname, FALSE));
-
- if (!is_nfs ())
- {
- /* Known remote file systems which can't handle calls to
- NtQueryDirectoryFile(FileIdBothDirectoryInformation) */
- RtlInitUnicodeString (&testname, L"UNIXFS");
- has_buggy_fileid_dirinfo (RtlEqualUnicodeString (&fsname,
- &testname,
- FALSE));
-
- /* Known remote file systems with buggy open calls. Further
- explanation in fhandler.cc (fhandler_disk_file::open). */
- RtlInitUnicodeString (&testname, L"SUNWNFS");
- has_buggy_open (RtlEqualUnicodeString (&fsname, &testname,
- FALSE));
- }
- }
- }
- is_ntfs (RtlEqualUnicodeString (&fsname, &testname, FALSE)
- && !is_samba () && !is_netapp ());
- is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM);
-
- has_acls (flags () & FS_PERSISTENT_ACLS);
- hasgood_inode (((flags () & FILE_PERSISTENT_ACLS) && !is_netapp ())
- || is_nfs ());
- /* Case sensitivity is supported if FILE_CASE_SENSITIVE_SEARCH is set,
- except on Samba which handles Windows clients case insensitive.
- NFS doesn't set the FILE_CASE_SENSITIVE_SEARCH flag but is case
- sensitive. */
- caseinsensitive ((!(flags () & FILE_CASE_SENSITIVE_SEARCH) || is_samba ())
- && !is_nfs ());
-
- if (!in_vol)
- NtClose (vol);
- return true;
-}
-
void
path_conv::fillin (HANDLE h)
{
details. */
#include "devices.h"
+#include "mount.h"
#include <sys/ioctl.h>
#include <fcntl.h>
};
class symlink_info;
-struct fs_info
-{
- private:
- struct status_flags
- {
- ULONG flags; /* Volume flags */
- ULONG samba_version; /* Samba version if available */
- ULONG name_len; /* MaximumComponentNameLength */
- unsigned is_remote_drive : 1;
- unsigned has_buggy_open : 1;
- unsigned has_buggy_fileid_dirinfo : 1;
- unsigned has_acls : 1;
- unsigned hasgood_inode : 1;
- unsigned caseinsensitive : 1;
- unsigned is_fat : 1;
- unsigned is_ntfs : 1;
- unsigned is_samba : 1;
- unsigned is_nfs : 1;
- unsigned is_netapp : 1;
- unsigned is_cdrom : 1;
- } status;
- ULONG sernum;
- public:
- void clear () { memset (&status, 0 , sizeof status); sernum = 0UL; }
- fs_info () { clear (); }
-
- IMPLEMENT_STATUS_FLAG (ULONG, flags)
- IMPLEMENT_STATUS_FLAG (ULONG, samba_version)
- IMPLEMENT_STATUS_FLAG (ULONG, name_len)
- IMPLEMENT_STATUS_FLAG (bool, is_remote_drive)
- IMPLEMENT_STATUS_FLAG (bool, has_buggy_open)
- IMPLEMENT_STATUS_FLAG (bool, has_buggy_fileid_dirinfo)
- IMPLEMENT_STATUS_FLAG (bool, has_acls)
- IMPLEMENT_STATUS_FLAG (bool, hasgood_inode)
- IMPLEMENT_STATUS_FLAG (bool, caseinsensitive)
- IMPLEMENT_STATUS_FLAG (bool, is_fat)
- IMPLEMENT_STATUS_FLAG (bool, is_ntfs)
- IMPLEMENT_STATUS_FLAG (bool, is_samba)
- IMPLEMENT_STATUS_FLAG (bool, is_nfs)
- IMPLEMENT_STATUS_FLAG (bool, is_netapp)
- IMPLEMENT_STATUS_FLAG (bool, is_cdrom)
- ULONG serial_number () const { return sernum; }
-
- bool update (PUNICODE_STRING, HANDLE) __attribute__ ((regparm (3)));
-};
class path_conv
{
#include "security.h"
#include "mtinfo.h"
#include "limits.h"
-
-/* Mount table entry */
-
-class mount_item
-{
- public:
- /* FIXME: Nasty static allocation. Need to have a heap in the shared
- area [with the user being able to configure at runtime the max size]. */
- /* Win32-style mounted partition source ("C:\foo\bar").
- native_path[0] == 0 for unused entries. */
- char native_path[CYG_MAX_PATH];
- int native_pathlen;
-
- /* POSIX-style mount point ("/foo/bar") */
- char posix_path[CYG_MAX_PATH];
- int posix_pathlen;
-
- unsigned flags;
-
- void init (const char *dev, const char *path, unsigned flags);
-
- struct mntent *getmntent ();
- int build_win32 (char *, const char *, unsigned *, unsigned);
-};
-
-/* Warning: Decreasing this value will cause cygwin.dll to ignore existing
- higher numbered registry entries. Don't change this number willy-nilly.
- What we need is to have a more dynamic allocation scheme, but the current
- scheme should be satisfactory for a long while yet. */
-#define MAX_MOUNTS 30
-
-#define USER_VERSION 1 // increment when mount table changes and
-#define USER_VERSION_MAGIC CYGWIN_VERSION_MAGIC (USER_MAGIC, USER_VERSION)
-#define CURR_USER_MAGIC 0xb2232e71U
-
-class reg_key;
-struct device;
-
-/* NOTE: Do not make gratuitous changes to the names or organization of the
- below class. The layout is checksummed to determine compatibility between
- different cygwin versions. */
-class mount_info
-{
- public:
- DWORD sys_mount_table_counter;
- int nmounts;
- mount_item mount[MAX_MOUNTS];
-
- /* cygdrive_prefix is used as the root of the path automatically
- prepended to a path when the path has no associated mount.
- cygdrive_flags are the default flags for the cygdrives. */
- char cygdrive[CYG_MAX_PATH];
- size_t cygdrive_len;
- unsigned cygdrive_flags;
- private:
- int posix_sorted[MAX_MOUNTS];
- int native_sorted[MAX_MOUNTS];
-
- public:
- void init ();
- int add_item (const char *dev, const char *path, unsigned flags);
- int del_item (const char *path, unsigned flags);
-
- unsigned set_flags_from_win32_path (const char *path);
- int conv_to_win32_path (const char *src_path, char *dst, device&,
- unsigned *flags = NULL);
- int conv_to_posix_path (PWCHAR src_path, char *posix_path,
- int keep_rel_p);
- int conv_to_posix_path (const char *src_path, char *posix_path,
- int keep_rel_p);
- struct mntent *getmntent (int x);
-
- int write_cygdrive_info (const char *cygdrive_prefix, unsigned flags);
- int get_cygdrive_info (char *user, char *system, char* user_flags,
- char* system_flags);
- void cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p);
- int get_mounts_here (const char *parent_dir, int,
- PUNICODE_STRING mount_points,
- PUNICODE_STRING cygd);
-
- private:
- void sort ();
- void mount_slash ();
- void create_root_entry (const PWCHAR root);
-
- bool from_fstab_line (char *line, bool user);
- bool from_fstab (bool user, WCHAR [], PWCHAR);
-
- int cygdrive_win32_path (const char *src, char *dst, int& unit);
-};
+#include "mount.h"
class user_info
{