aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2008-01-22 17:43:22 +0000
committerCorinna Vinschen <corinna@vinschen.de>2008-01-22 17:43:22 +0000
commit4a96b0aa85fe8a4cabebf17229431e76f8b3453e (patch)
tree5ed427963780aeb198c3ea593b7a00aefe88a7b7
parent226f5a32da9ff0311c3513f48167fce52d591632 (diff)
downloadnewlib-4a96b0aa85fe8a4cabebf17229431e76f8b3453e.zip
newlib-4a96b0aa85fe8a4cabebf17229431e76f8b3453e.tar.gz
newlib-4a96b0aa85fe8a4cabebf17229431e76f8b3453e.tar.bz2
* ntdll.h (struct _FILE_FS_OBJECTID_INFORMATION): Define.
* path.cc (struct smb_extended_info): Define. (fs_info::update): Request object id info to get Samba information. Set flags according to new implementation. * path.h (struct fs_info): Add samba_version to status_flags. Implement flags() and samba_version() using IMPLEMENT_STATUS_FLAG.
-rw-r--r--winsup/cygwin/ChangeLog9
-rw-r--r--winsup/cygwin/ntdll.h5
-rw-r--r--winsup/cygwin/path.cc51
-rw-r--r--winsup/cygwin/path.h9
4 files changed, 62 insertions, 12 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 19aadbe..7d82ed2 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,12 @@
+2008-01-22 Corinna Vinschen <corinna@vinschen.de>
+
+ * ntdll.h (struct _FILE_FS_OBJECTID_INFORMATION): Define.
+ * path.cc (struct smb_extended_info): Define.
+ (fs_info::update): Request object id info to get Samba information.
+ Set flags according to new implementation.
+ * path.h (struct fs_info): Add samba_version to status_flags.
+ Implement flags() and samba_version() using IMPLEMENT_STATUS_FLAG.
+
2008-01-21 Corinna Vinschen <corinna@vinschen.de>
* fhandler_disk_file.cc (fhandler_disk_file::link): Open file with
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index fa1beee..91ddf28 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -712,6 +712,11 @@ typedef struct _FILE_FS_FULL_SIZE_INFORMATION
ULONG BytesPerSector;
} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION;
+typedef struct _FILE_FS_OBJECTID_INFORMATION {
+ UCHAR ObjectId[16];
+ UCHAR ExtendedInfo[48];
+} FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION;
+
typedef enum _FSINFOCLASS {
FileFsVolumeInformation = 1,
FileFsLabelInformation,
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 2f77464..d24d859 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -378,6 +378,22 @@ mkrelpath (char *path)
strcpy (path, ".");
}
+/* Beginning with Samba 3.2, 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, bool exists)
{
@@ -387,6 +403,7 @@ fs_info::update (PUNICODE_STRING upath, bool exists)
IO_STATUS_BLOCK io;
bool no_media = false;
FILE_FS_DEVICE_INFORMATION ffdi;
+ FILE_FS_OBJECTID_INFORMATION ffoi;
PFILE_FS_ATTRIBUTE_INFORMATION pffai;
UNICODE_STRING fsname, testname;
@@ -444,11 +461,11 @@ fs_info::update (PUNICODE_STRING upath, bool exists)
debug_printf ("Cannot get volume attributes (%S), %08lx",
attr.ObjectName, status);
has_buggy_open (false);
- flags () = 0;
+ flags (0);
NtClose (vol);
return false;
}
- flags () = pffai->FileSystemAttributes;
+ flags (pffai->FileSystemAttributes);
/* 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
@@ -476,12 +493,30 @@ fs_info::update (PUNICODE_STRING upath, bool exists)
pffai->FileSystemNameLength);
is_fat (RtlEqualUnicodePathPrefix (&fsname, L"FAT", TRUE));
RtlInitUnicodeString (&testname, L"NTFS");
- is_samba (RtlEqualUnicodeString (&fsname, &testname, FALSE)
- && (ffdi.Characteristics & FILE_REMOTE_DEVICE)
- && (FS_IS_SAMBA || FS_IS_SAMBA_WITH_QUOTA));
- is_netapp (RtlEqualUnicodeString (&fsname, &testname, FALSE)
- && (ffdi.Characteristics & FILE_REMOTE_DEVICE)
- && FS_IS_NETAPP_DATAONTAP);
+ 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 older Samba releases not supporting the extended info. */
+ if (!is_samba ())
+ is_samba (RtlEqualUnicodeString (&fsname, &testname, FALSE)
+ && (FS_IS_SAMBA || FS_IS_SAMBA_WITH_QUOTA));
+
+ is_netapp (!is_samba ()
+ && RtlEqualUnicodeString (&fsname, &testname, FALSE)
+ && FS_IS_NETAPP_DATAONTAP);
+ }
is_ntfs (RtlEqualUnicodeString (&fsname, &testname, FALSE)
&& !is_samba () && !is_netapp ());
RtlInitUnicodeString (&testname, L"NFS");
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index 5bf9717..a19f382 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -97,7 +97,8 @@ struct fs_info
private:
struct status_flags
{
- DWORD flags; /* Volume flags */
+ DWORD flags; /* Volume flags */
+ DWORD samba_version; /* Samba version if available */
unsigned is_remote_drive : 1;
unsigned has_buggy_open : 1;
unsigned has_acls : 1;
@@ -110,11 +111,11 @@ struct fs_info
unsigned is_cdrom : 1;
} status;
public:
- void clear () { memset (this, 0 , sizeof *this); }
+ void clear () { memset (&status, 0 , sizeof status); }
fs_info () { clear (); }
- inline DWORD& flags () {return status.flags;};
-
+ IMPLEMENT_STATUS_FLAG (DWORD, flags)
+ IMPLEMENT_STATUS_FLAG (DWORD, samba_version)
IMPLEMENT_STATUS_FLAG (bool, is_remote_drive)
IMPLEMENT_STATUS_FLAG (bool, has_buggy_open)
IMPLEMENT_STATUS_FLAG (bool, has_acls)