Revise the DOS attributes patch to simplify the addition of extended attributes.

This commit is contained in:
Erich E. Hoover 2014-08-20 22:29:46 -06:00
parent 6fa663e823
commit d447778cfb
17 changed files with 468 additions and 489 deletions

View File

@ -442,10 +442,9 @@ ntdll-DOS_Attributes.ok:
$(call APPLY_FILE,ntdll-DOS_Attributes/0001-ntdll-Unify-retrieving-the-attributes-of-a-file.patch)
$(call APPLY_FILE,ntdll-DOS_Attributes/0002-ntdll-Implement-retrieving-DOS-attributes-in-NtQuery.patch)
$(call APPLY_FILE,ntdll-DOS_Attributes/0003-ntdll-Implement-retrieving-DOS-attributes-in-NtQuery.patch)
$(call APPLY_FILE,ntdll-DOS_Attributes/0004-ntdll-Implement-retrieving-DOS-attributes-in-NtQuery.patch)
$(call APPLY_FILE,ntdll-DOS_Attributes/0005-ntdll-Implement-storing-DOS-attributes-in-NtSetInfor.patch)
$(call APPLY_FILE,ntdll-DOS_Attributes/0006-ntdll-Implement-storing-DOS-attributes-in-NtCreateFi.patch)
$(call APPLY_FILE,ntdll-DOS_Attributes/0007-ntdll-Perform-the-Unix-style-hidden-file-check-withi.patch)
$(call APPLY_FILE,ntdll-DOS_Attributes/0004-ntdll-Implement-storing-DOS-attributes-in-NtSetInfor.patch)
$(call APPLY_FILE,ntdll-DOS_Attributes/0005-ntdll-Implement-storing-DOS-attributes-in-NtCreateFi.patch)
$(call APPLY_FILE,ntdll-DOS_Attributes/0006-ntdll-Perform-the-Unix-style-hidden-file-check-withi.patch)
@( \
echo '+ { "ntdll-DOS_Attributes", "Erich E. Hoover", "Implement DOS hidden/system file attributes" },'; \
) > ntdll-DOS_Attributes.ok
@ -540,7 +539,7 @@ ntdll-Junction_Points.ok:
$(call APPLY_FILE,ntdll-Junction_Points/0001-ntdll-Add-support-for-junction-point-creation.patch)
$(call APPLY_FILE,ntdll-Junction_Points/0002-ntdll-Add-support-for-reading-junction-points.patch)
$(call APPLY_FILE,ntdll-Junction_Points/0003-ntdll-Add-support-for-deleting-junction-points.patch)
$(call APPLY_FILE,ntdll-Junction_Points/0004-ntdll-Advertise-that-a-file-is-a-junction-point.patch)
$(call APPLY_FILE,ntdll-Junction_Points/0004-ntdll-Add-a-test-for-junction-point-advertisement.patch)
$(call APPLY_FILE,ntdll-Junction_Points/0005-kernel32-ntdll-Add-support-for-deleting-junction-poi.patch)
$(call APPLY_FILE,ntdll-Junction_Points/0006-kernel32-Advertise-junction-point-support.patch)
$(call APPLY_FILE,ntdll-Junction_Points/0007-ntdll-tests-Add-test-for-deleting-junction-point-tar.patch)

View File

@ -1,19 +1,60 @@
From 7922ba3b2a5414d30053821394962afed4e5b13c Mon Sep 17 00:00:00 2001
From b331ed482682444dfeb31358977a2645c5c194f4 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Tue, 19 Aug 2014 20:31:00 -0600
Subject: ntdll: Unify retrieving the attributes of a file.
---
dlls/ntdll/file.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
dlls/ntdll/directory.c | 12 ++----
dlls/ntdll/file.c | 107 ++++++++++++++++++++++++++++++++++-------------
dlls/ntdll/ntdll_misc.h | 4 +-
3 files changed, 83 insertions(+), 40 deletions(-)
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index a2796b2..dad2ee2 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -1380,7 +1380,7 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
WCHAR short_nameW[12];
WCHAR *filename;
UNICODE_STRING str;
- ULONG attributes = 0;
+ ULONG attributes;
io->u.Status = STATUS_SUCCESS;
long_len = ntdll_umbstowcs( 0, long_name, strlen(long_name), long_nameW, MAX_DIR_ENTRY_LEN );
@@ -1417,12 +1417,7 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
if (!match_filename( &str, mask )) return NULL;
}
- if (lstat( long_name, &st ) == -1) return NULL;
- if (S_ISLNK( st.st_mode ))
- {
- if (stat( long_name, &st ) == -1) return NULL;
- if (S_ISDIR( st.st_mode )) attributes |= FILE_ATTRIBUTE_REPARSE_POINT;
- }
+ if (get_file_info( long_name, &st, &attributes ) == -1) return NULL;
if (is_ignored_file( &st ))
{
TRACE( "ignoring file %s\n", long_name );
@@ -1440,10 +1435,9 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
info = (union file_directory_info *)((char *)info_ptr + io->Information);
if (st.st_dev != curdir.dev) st.st_ino = 0; /* ignore inode if on a different device */
/* all the structures start with a FileDirectoryInformation layout */
- fill_stat_info( &st, info, class );
+ fill_file_info( attributes, &st, info, class );
info->dir.NextEntryOffset = total_len;
info->dir.FileIndex = 0; /* NTFS always has 0 here, so let's not bother with it */
- info->dir.FileAttributes |= attributes;
switch (class)
{
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 92d9829..78c375a 100644
index 92d9829..4ec2c34 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1774,6 +1774,21 @@ static inline void get_file_times( const struct stat *st, LARGE_INTEGER *mtime,
#endif
}
@@ -103,6 +103,55 @@ mode_t FILE_umask = 0;
static const WCHAR ntfsW[] = {'N','T','F','S'};
+/* fetch the attributes of a file */
+static inline ULONG get_file_attributes( const struct stat *st )
@ -29,11 +70,57 @@ index 92d9829..78c375a 100644
+ return attr;
+}
+
+/* get the stat info and file attributes for a file (by file descriptor) */
+int fd_get_file_info( int fd, struct stat *st, ULONG *attr )
+{
+ int ret;
+
/* fill in the file information that depends on the stat info */
NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class )
+ *attr = 0;
+ ret = fstat( fd, st );
+ if (ret == -1) return ret;
+ /* convert the Unix stat info into file attributes */
+ *attr |= get_file_attributes( st );
+ return ret;
+}
+
+/* get the stat info and file attributes for a file (by name) */
+int get_file_info( const char *path, struct stat *st, ULONG *attr )
+{
+ int ret;
+
+ *attr = 0;
+ /* stat the file and don't follow symbol links */
+ ret = lstat( path, st );
+ if (ret == -1) return ret;
+ if (S_ISLNK( st->st_mode ))
+ {
+ /* stat the file but follow symbol links */
+ ret = stat( path, st );
+ if (ret == -1) return ret;
+ /* is a symbolic link and a directory, consider these "reparse points" */
+ if (S_ISDIR( st->st_mode )) *attr |= FILE_ATTRIBUTE_REPARSE_POINT;
+ }
+ /* convert the Unix stat info into file attributes */
+ *attr |= get_file_attributes( st );
+ return ret;
+}
+
/**************************************************************************
* FILE_CreateFile (internal)
* Open a file.
@@ -1774,8 +1823,9 @@ static inline void get_file_times( const struct stat *st, LARGE_INTEGER *mtime,
#endif
}
-/* fill in the file information that depends on the stat info */
-NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class )
+/* fill in the file information that depends on the stat and attribute info */
+NTSTATUS fill_file_info( const ULONG attr, const struct stat *st, void *ptr,
+ FILE_INFORMATION_CLASS class )
{
@@ -1785,10 +1800,7 @@ NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLAS
switch (class)
{
@@ -1785,10 +1835,7 @@ NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLAS
get_file_times( st, &info->LastWriteTime, &info->ChangeTime,
&info->LastAccessTime, &info->CreationTime );
@ -41,11 +128,24 @@ index 92d9829..78c375a 100644
- else info->FileAttributes = FILE_ATTRIBUTE_ARCHIVE;
- if (!(st->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
- info->FileAttributes |= FILE_ATTRIBUTE_READONLY;
+ info->FileAttributes = get_file_attributes( st );
+ info->FileAttributes = attr;
}
break;
case FileStandardInformation:
@@ -1842,16 +1854,13 @@ NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLAS
@@ -1824,9 +1871,9 @@ NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLAS
case FileAllInformation:
{
FILE_ALL_INFORMATION *info = ptr;
- fill_stat_info( st, &info->BasicInformation, FileBasicInformation );
- fill_stat_info( st, &info->StandardInformation, FileStandardInformation );
- fill_stat_info( st, &info->InternalInformation, FileInternalInformation );
+ fill_file_info( attr, st, &info->BasicInformation, FileBasicInformation );
+ fill_file_info( attr, st, &info->StandardInformation, FileStandardInformation );
+ fill_file_info( attr, st, &info->InternalInformation, FileInternalInformation );
}
break;
/* all directory structures start with the FileDirectoryInformation layout */
@@ -1842,30 +1889,27 @@ NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLAS
{
info->AllocationSize.QuadPart = 0;
info->EndOfFile.QuadPart = 0;
@ -59,10 +159,155 @@ index 92d9829..78c375a 100644
}
- if (!(st->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
- info->FileAttributes |= FILE_ATTRIBUTE_READONLY;
+ info->FileAttributes = get_file_attributes( st );
+ info->FileAttributes = attr;
}
break;
case FileIdFullDirectoryInformation:
{
FILE_ID_FULL_DIRECTORY_INFORMATION *info = ptr;
info->FileId.QuadPart = st->st_ino;
- fill_stat_info( st, info, FileDirectoryInformation );
+ fill_file_info( attr, st, info, FileDirectoryInformation );
}
break;
case FileIdBothDirectoryInformation:
{
FILE_ID_BOTH_DIRECTORY_INFORMATION *info = ptr;
info->FileId.QuadPart = st->st_ino;
- fill_stat_info( st, info, FileDirectoryInformation );
+ fill_file_info( attr, st, info, FileDirectoryInformation );
}
break;
@@ -2017,6 +2061,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
struct stat st;
int fd, needs_close = FALSE;
+ ULONG attr;
TRACE("(%p,%p,%p,0x%08x,0x%08x)\n", hFile, io, ptr, len, class);
@@ -2041,21 +2086,21 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
switch (class)
{
case FileBasicInformation:
- if (fstat( fd, &st ) == -1)
+ if (fd_get_file_info( fd, &st, &attr ) == -1)
io->u.Status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
io->u.Status = STATUS_INVALID_INFO_CLASS;
else
- fill_stat_info( &st, ptr, class );
+ fill_file_info( attr, &st, ptr, class );
break;
case FileStandardInformation:
{
FILE_STANDARD_INFORMATION *info = ptr;
- if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
+ if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
else
{
- fill_stat_info( &st, info, class );
+ fill_file_info( attr, &st, info, class );
info->DeletePending = FALSE; /* FIXME */
}
}
@@ -2069,8 +2114,8 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
}
break;
case FileInternalInformation:
- if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
- else fill_stat_info( &st, ptr, class );
+ if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
+ else fill_file_info( attr, &st, ptr, class );
break;
case FileEaInformation:
{
@@ -2079,22 +2124,22 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
}
break;
case FileEndOfFileInformation:
- if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
- else fill_stat_info( &st, ptr, class );
+ if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
+ else fill_file_info( attr, &st, ptr, class );
break;
case FileAllInformation:
{
FILE_ALL_INFORMATION *info = ptr;
ANSI_STRING unix_name;
- if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
+ if (fd_get_file_info( fd, &st, &attr ) == -1) io->u.Status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
io->u.Status = STATUS_INVALID_INFO_CLASS;
else if (!(io->u.Status = server_get_unix_name( hFile, &unix_name )))
{
LONG name_len = len - FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName);
- fill_stat_info( &st, info, FileAllInformation );
+ fill_file_info( attr, &st, info, FileAllInformation );
info->StandardInformation.DeletePending = FALSE; /* FIXME */
info->EaInformation.EaSize = 0;
info->AccessInformation.AccessFlags = 0; /* FIXME */
@@ -2445,9 +2490,10 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
if (!(status = nt_to_unix_file_name_attr( attr, &unix_name, FILE_OPEN )))
{
+ ULONG attributes;
struct stat st;
- if (stat( unix_name.Buffer, &st ) == -1)
+ if (get_file_info( unix_name.Buffer, &st, &attributes ) == -1)
status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
status = STATUS_INVALID_INFO_CLASS;
@@ -2456,8 +2502,8 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
FILE_BASIC_INFORMATION basic;
FILE_STANDARD_INFORMATION std;
- fill_stat_info( &st, &basic, FileBasicInformation );
- fill_stat_info( &st, &std, FileStandardInformation );
+ fill_file_info( attributes, &st, &basic, FileBasicInformation );
+ fill_file_info( attributes, &st, &std, FileStandardInformation );
info->CreationTime = basic.CreationTime;
info->LastAccessTime = basic.LastAccessTime;
@@ -2487,15 +2533,16 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
if (!(status = nt_to_unix_file_name_attr( attr, &unix_name, FILE_OPEN )))
{
+ ULONG attributes;
struct stat st;
- if (stat( unix_name.Buffer, &st ) == -1)
+ if (get_file_info( unix_name.Buffer, &st, &attributes ) == -1)
status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
status = STATUS_INVALID_INFO_CLASS;
else
{
- status = fill_stat_info( &st, info, FileBasicInformation );
+ status = fill_file_info( attributes, &st, info, FileBasicInformation );
if (DIR_is_hidden_file( attr->ObjectName ))
info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
}
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 4370084..ae59552 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -148,7 +148,9 @@ extern NTSTATUS COMM_FlushBuffersFile( int fd ) DECLSPEC_HIDDEN;
/* file I/O */
struct stat;
extern NTSTATUS FILE_GetNtStatus(void) DECLSPEC_HIDDEN;
-extern NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class ) DECLSPEC_HIDDEN;
+extern int get_file_info( const char *path, struct stat *st, ULONG *attr ) DECLSPEC_HIDDEN;
+extern NTSTATUS fill_file_info( const ULONG attr, const struct stat *st, void *ptr,
+ FILE_INFORMATION_CLASS class ) DECLSPEC_HIDDEN;
extern NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ) DECLSPEC_HIDDEN;
extern void DIR_init_windows_dir( const WCHAR *windir, const WCHAR *sysdir ) DECLSPEC_HIDDEN;
extern BOOL DIR_is_hidden_file( const UNICODE_STRING *name ) DECLSPEC_HIDDEN;
--
1.7.9.5

View File

@ -1,18 +1,16 @@
From 07b0e6fe66d8ac19d7584f52a066d2957d858144 Mon Sep 17 00:00:00 2001
From 38c961e5a031c4394523843b4e85a6634e34423d Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Tue, 19 Aug 2014 22:10:49 -0600
Subject: ntdll: Implement retrieving DOS attributes in
NtQueryInformationFile.
---
configure.ac | 12 +++++++
dlls/ntdll/directory.c | 3 +-
dlls/ntdll/file.c | 80 ++++++++++++++++++++++++++++++++++++-----------
dlls/ntdll/ntdll_misc.h | 2 +-
include/wine/port.h | 11 +++++++
libs/port/Makefile.in | 3 +-
libs/port/xattr.c | 61 ++++++++++++++++++++++++++++++++++++
7 files changed, 150 insertions(+), 22 deletions(-)
configure.ac | 12 ++++++++++
dlls/ntdll/file.c | 30 +++++++++++++++++++++++-
include/wine/port.h | 11 +++++++++
libs/port/Makefile.in | 3 ++-
libs/port/xattr.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 115 insertions(+), 2 deletions(-)
create mode 100644 libs/port/xattr.c
diff --git a/configure.ac b/configure.ac
@ -45,32 +43,11 @@ index 7de7a87..b77c12f 100644
dnl **** Check for working dll ****
AC_SUBST(dlldir,"\${libdir}/wine")
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index a2796b2..678aef5 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -1381,6 +1381,7 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
WCHAR *filename;
UNICODE_STRING str;
ULONG attributes = 0;
+ ULONG xattr = 0;
io->u.Status = STATUS_SUCCESS;
long_len = ntdll_umbstowcs( 0, long_name, strlen(long_name), long_nameW, MAX_DIR_ENTRY_LEN );
@@ -1440,7 +1441,7 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
info = (union file_directory_info *)((char *)info_ptr + io->Information);
if (st.st_dev != curdir.dev) st.st_ino = 0; /* ignore inode if on a different device */
/* all the structures start with a FileDirectoryInformation layout */
- fill_stat_info( &st, info, class );
+ fill_file_info( xattr, &st, info, class );
info->dir.NextEntryOffset = total_len;
info->dir.FileIndex = 0; /* NTFS always has 0 here, so let's not bother with it */
info->dir.FileAttributes |= attributes;
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 78c375a..c8176dd 100644
index 4ec2c34..7985dcb 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -103,6 +103,41 @@ mode_t FILE_umask = 0;
@@ -103,6 +103,29 @@ mode_t FILE_umask = 0;
static const WCHAR ntfsW[] = {'N','T','F','S'};
@ -86,6 +63,7 @@ index 78c375a..c8176dd 100644
+/* We are only interested in some attributes, the others have corresponding Unix attributes */
+#define XATTR_ATTRIBS_MASK (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)
+
+/* decode the xattr-stored DOS attributes */
+static inline int get_file_xattr( char *hexattr, int attrlen )
+{
+ if (attrlen > 2 && hexattr[0] == '0' && hexattr[1] == 'x')
@ -96,213 +74,29 @@ index 78c375a..c8176dd 100644
+ return 0;
+}
+
+int fd_get_file_info( int fd, struct stat *st, ULONG *xattr )
+{
+ int len, ret = fstat( fd, st );
/* fetch the attributes of a file */
static inline ULONG get_file_attributes( const struct stat *st )
{
@@ -120,13 +143,18 @@ static inline ULONG get_file_attributes( const struct stat *st )
/* get the stat info and file attributes for a file (by file descriptor) */
int fd_get_file_info( int fd, struct stat *st, ULONG *attr )
{
- int ret;
+ char hexattr[10];
+
+ *xattr = 0;
+ if (ret == -1) return ret;
+ int len, ret;
*attr = 0;
ret = fstat( fd, st );
if (ret == -1) return ret;
/* convert the Unix stat info into file attributes */
*attr |= get_file_attributes( st );
+ /* retrieve any stored DOS attributes */
+ len = xattr_fget( fd, SAMBA_XATTR_DOS_ATTRIB, hexattr, sizeof(hexattr)-1 );
+ if (len == -1) return ret;
+ *xattr |= get_file_xattr( hexattr, len );
+ return ret;
+}
+
/**************************************************************************
* FILE_CreateFile (internal)
* Open a file.
@@ -1775,7 +1810,7 @@ static inline void get_file_times( const struct stat *st, LARGE_INTEGER *mtime,
+ *attr |= get_file_xattr( hexattr, len );
return ret;
}
/* fetch the attributes of a file */
-static inline ULONG get_file_attributes( const struct stat *st )
+static inline ULONG get_file_attributes( const ULONG xattr, const struct stat *st )
{
ULONG attr;
@@ -1783,6 +1818,10 @@ static inline ULONG get_file_attributes( const struct stat *st )
attr = FILE_ATTRIBUTE_DIRECTORY;
else
attr = FILE_ATTRIBUTE_ARCHIVE;
+
+ /* if any extended attributes exist then add them to the traditional attributes */
+ attr |= xattr;
+
if (!(st->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
attr |= FILE_ATTRIBUTE_READONLY;
return attr;
@@ -1790,7 +1829,7 @@ static inline ULONG get_file_attributes( const struct stat *st )
/* fill in the file information that depends on the stat info */
-NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class )
+NTSTATUS fill_file_info( const ULONG xattr, const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class )
{
switch (class)
{
@@ -1800,7 +1839,7 @@ NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLAS
get_file_times( st, &info->LastWriteTime, &info->ChangeTime,
&info->LastAccessTime, &info->CreationTime );
- info->FileAttributes = get_file_attributes( st );
+ info->FileAttributes = get_file_attributes( xattr, st );
}
break;
case FileStandardInformation:
@@ -1836,9 +1875,9 @@ NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLAS
case FileAllInformation:
{
FILE_ALL_INFORMATION *info = ptr;
- fill_stat_info( st, &info->BasicInformation, FileBasicInformation );
- fill_stat_info( st, &info->StandardInformation, FileStandardInformation );
- fill_stat_info( st, &info->InternalInformation, FileInternalInformation );
+ fill_file_info( xattr, st, &info->BasicInformation, FileBasicInformation );
+ fill_file_info( xattr, st, &info->StandardInformation, FileStandardInformation );
+ fill_file_info( xattr, st, &info->InternalInformation, FileInternalInformation );
}
break;
/* all directory structures start with the FileDirectoryInformation layout */
@@ -1860,21 +1899,21 @@ NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLAS
info->AllocationSize.QuadPart = (ULONGLONG)st->st_blocks * 512;
info->EndOfFile.QuadPart = st->st_size;
}
- info->FileAttributes = get_file_attributes( st );
+ info->FileAttributes = get_file_attributes( xattr, st );
}
break;
case FileIdFullDirectoryInformation:
{
FILE_ID_FULL_DIRECTORY_INFORMATION *info = ptr;
info->FileId.QuadPart = st->st_ino;
- fill_stat_info( st, info, FileDirectoryInformation );
+ fill_file_info( xattr, st, info, FileDirectoryInformation );
}
break;
case FileIdBothDirectoryInformation:
{
FILE_ID_BOTH_DIRECTORY_INFORMATION *info = ptr;
info->FileId.QuadPart = st->st_ino;
- fill_stat_info( st, info, FileDirectoryInformation );
+ fill_file_info( xattr, st, info, FileDirectoryInformation );
}
break;
@@ -2026,6 +2065,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
struct stat st;
int fd, needs_close = FALSE;
+ ULONG xattr;
TRACE("(%p,%p,%p,0x%08x,0x%08x)\n", hFile, io, ptr, len, class);
@@ -2050,12 +2090,12 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
switch (class)
{
case FileBasicInformation:
- if (fstat( fd, &st ) == -1)
+ if (fd_get_file_info( fd, &st, &xattr ) == -1)
io->u.Status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
io->u.Status = STATUS_INVALID_INFO_CLASS;
else
- fill_stat_info( &st, ptr, class );
+ fill_file_info( xattr, &st, ptr, class );
break;
case FileStandardInformation:
{
@@ -2064,7 +2104,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
else
{
- fill_stat_info( &st, info, class );
+ fill_file_info( xattr, &st, info, class );
info->DeletePending = FALSE; /* FIXME */
}
}
@@ -2079,7 +2119,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
break;
case FileInternalInformation:
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
- else fill_stat_info( &st, ptr, class );
+ else fill_file_info( xattr, &st, ptr, class );
break;
case FileEaInformation:
{
@@ -2089,21 +2129,21 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
break;
case FileEndOfFileInformation:
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
- else fill_stat_info( &st, ptr, class );
+ else fill_file_info( xattr, &st, ptr, class );
break;
case FileAllInformation:
{
FILE_ALL_INFORMATION *info = ptr;
ANSI_STRING unix_name;
- if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
+ if (fd_get_file_info( fd, &st, &xattr ) == -1) io->u.Status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
io->u.Status = STATUS_INVALID_INFO_CLASS;
else if (!(io->u.Status = server_get_unix_name( hFile, &unix_name )))
{
LONG name_len = len - FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName);
- fill_stat_info( &st, info, FileAllInformation );
+ fill_file_info( xattr, &st, info, FileAllInformation );
info->StandardInformation.DeletePending = FALSE; /* FIXME */
info->EaInformation.EaSize = 0;
info->AccessInformation.AccessFlags = 0; /* FIXME */
@@ -2455,6 +2495,7 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
if (!(status = nt_to_unix_file_name_attr( attr, &unix_name, FILE_OPEN )))
{
struct stat st;
+ ULONG xattr = 0;
if (stat( unix_name.Buffer, &st ) == -1)
status = FILE_GetNtStatus();
@@ -2465,8 +2506,8 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
FILE_BASIC_INFORMATION basic;
FILE_STANDARD_INFORMATION std;
- fill_stat_info( &st, &basic, FileBasicInformation );
- fill_stat_info( &st, &std, FileStandardInformation );
+ fill_file_info( xattr, &st, &basic, FileBasicInformation );
+ fill_file_info( xattr, &st, &std, FileStandardInformation );
info->CreationTime = basic.CreationTime;
info->LastAccessTime = basic.LastAccessTime;
@@ -2497,6 +2538,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
if (!(status = nt_to_unix_file_name_attr( attr, &unix_name, FILE_OPEN )))
{
struct stat st;
+ ULONG xattr = 0;
if (stat( unix_name.Buffer, &st ) == -1)
status = FILE_GetNtStatus();
@@ -2504,7 +2546,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
status = STATUS_INVALID_INFO_CLASS;
else
{
- status = fill_stat_info( &st, info, FileBasicInformation );
+ status = fill_file_info( xattr, &st, info, FileBasicInformation );
if (DIR_is_hidden_file( attr->ObjectName ))
info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
}
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 4370084..ec96427 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -148,7 +148,7 @@ extern NTSTATUS COMM_FlushBuffersFile( int fd ) DECLSPEC_HIDDEN;
/* file I/O */
struct stat;
extern NTSTATUS FILE_GetNtStatus(void) DECLSPEC_HIDDEN;
-extern NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class ) DECLSPEC_HIDDEN;
+extern NTSTATUS fill_file_info( ULONG xattr, const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class ) DECLSPEC_HIDDEN;
extern NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ) DECLSPEC_HIDDEN;
extern void DIR_init_windows_dir( const WCHAR *windir, const WCHAR *sysdir ) DECLSPEC_HIDDEN;
extern BOOL DIR_is_hidden_file( const UNICODE_STRING *name ) DECLSPEC_HIDDEN;
diff --git a/include/wine/port.h b/include/wine/port.h
index 3548a44..715a9e2 100644
--- a/include/wine/port.h

View File

@ -1,70 +1,40 @@
From aca454765b4a1cd8b7a50761fb0bd9f82043b895 Mon Sep 17 00:00:00 2001
From 89997cb9e557658b23bb4dd00273f5d2f9082fc9 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Wed, 20 Aug 2014 16:04:34 -0600
Subject: ntdll: Implement retrieving DOS attributes in
NtQuery[Full]AttributesFile.
NtQuery[Full]AttributesFile and NtQueryDirectoryFile.
---
dlls/ntdll/file.c | 28 ++++++++++++++++++++++++----
dlls/ntdll/file.c | 7 ++++++-
include/wine/port.h | 1 +
libs/port/xattr.c | 16 ++++++++++++++++
3 files changed, 41 insertions(+), 4 deletions(-)
3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index c8176dd..8b2f398 100644
index 7985dcb..25815a5 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -138,6 +138,26 @@ int fd_get_file_info( int fd, struct stat *st, ULONG *xattr )
@@ -161,7 +161,8 @@ int fd_get_file_info( int fd, struct stat *st, ULONG *attr )
/* get the stat info and file attributes for a file (by name) */
int get_file_info( const char *path, struct stat *st, ULONG *attr )
{
- int ret;
+ char hexattr[10];
+ int len, ret;
*attr = 0;
/* stat the file and don't follow symbol links */
@@ -177,6 +178,10 @@ int get_file_info( const char *path, struct stat *st, ULONG *attr )
}
/* convert the Unix stat info into file attributes */
*attr |= get_file_attributes( st );
+ /* retrieve any stored DOS attributes */
+ len = xattr_get( path, SAMBA_XATTR_DOS_ATTRIB, hexattr, sizeof(hexattr)-1 );
+ if (len == -1) return ret;
+ *attr |= get_file_xattr( hexattr, len );
return ret;
}
+int get_file_info( const char *path, struct stat *st, ULONG *xattr )
+{
+ char hexattr[10];
+ int len, ret;
+
+ *xattr = 0;
+ ret = lstat( path, st );
+ if (ret == -1) return ret;
+ if (S_ISLNK( st->st_mode ))
+ {
+ ret = stat( path, st );
+ if (ret == -1) return ret;
+ if (S_ISDIR( st->st_mode )) *xattr |= FILE_ATTRIBUTE_REPARSE_POINT;
+ }
+ len = xattr_get( path, SAMBA_XATTR_DOS_ATTRIB, hexattr, sizeof(hexattr)-1 );
+ if (len == -1) return ret;
+ *xattr |= get_file_xattr( hexattr, len );
+ return ret;
+}
+
/**************************************************************************
* FILE_CreateFile (internal)
* Open a file.
@@ -2495,9 +2515,9 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
if (!(status = nt_to_unix_file_name_attr( attr, &unix_name, FILE_OPEN )))
{
struct stat st;
- ULONG xattr = 0;
+ ULONG xattr;
- if (stat( unix_name.Buffer, &st ) == -1)
+ if (get_file_info( unix_name.Buffer, &st, &xattr ) == -1)
status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
status = STATUS_INVALID_INFO_CLASS;
@@ -2538,9 +2558,9 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
if (!(status = nt_to_unix_file_name_attr( attr, &unix_name, FILE_OPEN )))
{
struct stat st;
- ULONG xattr = 0;
+ ULONG xattr;
- if (stat( unix_name.Buffer, &st ) == -1)
+ if (get_file_info( unix_name.Buffer, &st, &xattr ) == -1)
status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
status = STATUS_INVALID_INFO_CLASS;
diff --git a/include/wine/port.h b/include/wine/port.h
index 715a9e2..7d8ea1a 100644
--- a/include/wine/port.h

View File

@ -1,52 +0,0 @@
From 2e97bfb51b37d8b3bd85a486b706bb1608ebd132 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Wed, 20 Aug 2014 16:05:38 -0600
Subject: ntdll: Implement retrieving DOS attributes in NtQueryDirectoryFile.
---
dlls/ntdll/directory.c | 9 ++-------
dlls/ntdll/ntdll_misc.h | 1 +
2 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 678aef5..9fb4b87 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -1381,7 +1381,7 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
WCHAR *filename;
UNICODE_STRING str;
ULONG attributes = 0;
- ULONG xattr = 0;
+ ULONG xattr;
io->u.Status = STATUS_SUCCESS;
long_len = ntdll_umbstowcs( 0, long_name, strlen(long_name), long_nameW, MAX_DIR_ENTRY_LEN );
@@ -1418,12 +1418,7 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
if (!match_filename( &str, mask )) return NULL;
}
- if (lstat( long_name, &st ) == -1) return NULL;
- if (S_ISLNK( st.st_mode ))
- {
- if (stat( long_name, &st ) == -1) return NULL;
- if (S_ISDIR( st.st_mode )) attributes |= FILE_ATTRIBUTE_REPARSE_POINT;
- }
+ if (get_file_info( long_name, &st, &xattr ) == -1) return NULL;
if (is_ignored_file( &st ))
{
TRACE( "ignoring file %s\n", long_name );
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index ec96427..226bc85 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -148,6 +148,7 @@ extern NTSTATUS COMM_FlushBuffersFile( int fd ) DECLSPEC_HIDDEN;
/* file I/O */
struct stat;
extern NTSTATUS FILE_GetNtStatus(void) DECLSPEC_HIDDEN;
+extern int get_file_info( const char *path, struct stat *st, ULONG *xattr ) DECLSPEC_HIDDEN;
extern NTSTATUS fill_file_info( ULONG xattr, const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class ) DECLSPEC_HIDDEN;
extern NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ) DECLSPEC_HIDDEN;
extern void DIR_init_windows_dir( const WCHAR *windir, const WCHAR *sysdir ) DECLSPEC_HIDDEN;
--
1.7.9.5

View File

@ -1,29 +1,31 @@
From 1313cd2f5b09593702acd6d71187afdd50ccea4d Mon Sep 17 00:00:00 2001
From 05a50c64745b3af4e439702aade6aefb1d3c6040 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Wed, 20 Aug 2014 00:08:52 -0600
Subject: ntdll: Implement storing DOS attributes in NtSetInformationFile.
---
dlls/ntdll/file.c | 50 ++++++++++++++++++++++++++++-------------------
dlls/ntdll/tests/file.c | 8 ++++----
dlls/ntdll/file.c | 53 +++++++++++++++++++++++++++++------------------
dlls/ntdll/tests/file.c | 8 +++----
include/wine/port.h | 2 ++
libs/port/xattr.c | 31 +++++++++++++++++++++++++++++
4 files changed, 67 insertions(+), 24 deletions(-)
libs/port/xattr.c | 31 +++++++++++++++++++++++++++
4 files changed, 70 insertions(+), 24 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 8b2f398..1294888 100644
index 25815a5..70f8ea3 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -138,6 +138,35 @@ int fd_get_file_info( int fd, struct stat *st, ULONG *xattr )
@@ -158,6 +158,38 @@ int fd_get_file_info( int fd, struct stat *st, ULONG *attr )
return ret;
}
+/* set the stat info and file attributes for a file (by file descriptor) */
+NTSTATUS fd_set_file_info( int fd, ULONG attr )
+{
+ char hexattr[10];
+ struct stat st;
+ int len;
+
+ /* convert the file attributes into Unix stat info */
+ if (fstat( fd, &st ) == -1) return FILE_GetNtStatus();
+ if (attr & FILE_ATTRIBUTE_READONLY)
+ {
@ -39,6 +41,7 @@ index 8b2f398..1294888 100644
+ }
+ if (fchmod( fd, st.st_mode ) == -1) return FILE_GetNtStatus();
+ attr &= ~FILE_ATTRIBUTE_NORMAL; /* do not store everything, but keep everything Samba can use */
+ /* store/unset any possible DOS attributes */
+ len = sprintf( hexattr, "0x%x", attr );
+ if (attr != 0)
+ xattr_fset( fd, SAMBA_XATTR_DOS_ATTRIB, hexattr, len );
@ -47,10 +50,10 @@ index 8b2f398..1294888 100644
+ return STATUS_SUCCESS;
+}
+
int get_file_info( const char *path, struct stat *st, ULONG *xattr )
/* get the stat info and file attributes for a file (by name) */
int get_file_info( const char *path, struct stat *st, ULONG *attr )
{
char hexattr[10];
@@ -2324,7 +2353,6 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
@@ -2333,7 +2365,6 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
case FileBasicInformation:
if (len >= sizeof(FILE_BASIC_INFORMATION))
{
@ -58,7 +61,7 @@ index 8b2f398..1294888 100644
const FILE_BASIC_INFORMATION *info = ptr;
if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )))
@@ -2334,25 +2362,7 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
@@ -2343,25 +2374,7 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
io->u.Status = set_file_times( fd, &info->LastWriteTime, &info->LastAccessTime );
if (io->u.Status == STATUS_SUCCESS && info->FileAttributes)

View File

@ -1,4 +1,4 @@
From f9c827c6a03c5741aebdcada20d512c9ceb44284 Mon Sep 17 00:00:00 2001
From 48f69113889b2d83596fe350caf3085fa16f9bf2 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Wed, 20 Aug 2014 15:28:00 -0600
Subject: ntdll: Implement storing DOS attributes in NtCreateFile.
@ -11,10 +11,10 @@ Subject: ntdll: Implement storing DOS attributes in NtCreateFile.
4 files changed, 91 insertions(+), 44 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 1294888..6c278eb 100644
index 70f8ea3..e8e5b28 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -187,6 +187,21 @@ int get_file_info( const char *path, struct stat *st, ULONG *xattr )
@@ -217,6 +217,21 @@ int get_file_info( const char *path, struct stat *st, ULONG *attr )
return ret;
}
@ -36,7 +36,7 @@ index 1294888..6c278eb 100644
/**************************************************************************
* FILE_CreateFile (internal)
* Open a file.
@@ -198,6 +213,8 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
@@ -228,6 +243,8 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
ULONG attributes, ULONG sharing, ULONG disposition,
ULONG options, PVOID ea_buffer, ULONG ea_length )
{
@ -45,7 +45,7 @@ index 1294888..6c278eb 100644
ANSI_STRING unix_name;
BOOL created = FALSE;
@@ -240,40 +257,37 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
@@ -270,40 +287,37 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
created = TRUE;
io->u.Status = STATUS_SUCCESS;
}
@ -113,7 +113,7 @@ index 1294888..6c278eb 100644
if (io->u.Status == STATUS_SUCCESS)
{
@@ -295,6 +309,11 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
@@ -325,6 +339,11 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
io->Information = FILE_OVERWRITTEN;
break;
}
@ -125,7 +125,7 @@ index 1294888..6c278eb 100644
}
else if (io->u.Status == STATUS_TOO_MANY_OPENED_FILES)
{
@@ -302,6 +321,7 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
@@ -332,6 +351,7 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
if (!once++) ERR_(winediag)( "Too many open files, ulimit -n probably needs to be increased\n" );
}

View File

@ -1,17 +1,17 @@
From 398cf0a70a0d313bf84c4ff8335f49ca68e1ee84 Mon Sep 17 00:00:00 2001
From d1baa99fa107d76bd8714774ea9e5ca1d6c1c996 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Wed, 20 Aug 2014 11:26:48 -0600
Subject: ntdll: Perform the Unix-style hidden file check within the unified
file info grabbing routine.
---
dlls/ntdll/directory.c | 15 +++++----------
dlls/ntdll/file.c | 8 ++------
dlls/ntdll/directory.c | 13 +++++--------
dlls/ntdll/file.c | 9 +++------
dlls/ntdll/ntdll_misc.h | 2 +-
3 files changed, 8 insertions(+), 17 deletions(-)
3 files changed, 9 insertions(+), 15 deletions(-)
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 9fb4b87..726af4d 100644
index dad2ee2..0963207 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -1198,17 +1198,17 @@ static DWORD WINAPI init_options( RTL_RUN_ONCE *once, void *param, void **contex
@ -37,15 +37,7 @@ index 9fb4b87..726af4d 100644
if (p == end || *p != '.') return FALSE;
/* make sure it isn't '.' or '..' */
if (p + 1 == end) return FALSE;
@@ -1380,7 +1380,6 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
WCHAR short_nameW[12];
WCHAR *filename;
UNICODE_STRING str;
- ULONG attributes = 0;
ULONG xattr;
io->u.Status = STATUS_SUCCESS;
@@ -1424,9 +1423,6 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
@@ -1423,9 +1423,6 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
TRACE( "ignoring file %s\n", long_name );
return NULL;
}
@ -55,28 +47,21 @@ index 9fb4b87..726af4d 100644
total_len = dir_info_size( class, long_len );
if (io->Information + total_len > max_length)
{
@@ -1439,7 +1435,6 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
fill_file_info( xattr, &st, info, class );
info->dir.NextEntryOffset = total_len;
info->dir.FileIndex = 0; /* NTFS always has 0 here, so let's not bother with it */
- info->dir.FileAttributes |= attributes;
switch (class)
{
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 6c278eb..91f96ee 100644
index e8e5b28..7b72876 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -173,6 +173,8 @@ int get_file_info( const char *path, struct stat *st, ULONG *xattr )
int len, ret;
*xattr = 0;
@@ -210,6 +210,9 @@ int get_file_info( const char *path, struct stat *st, ULONG *attr )
}
/* convert the Unix stat info into file attributes */
*attr |= get_file_attributes( st );
+ /* convert Unix-style hidden files to a DOS hidden file attribute */
+ if (DIR_is_hidden_file( path ))
+ *xattr |= FILE_ATTRIBUTE_HIDDEN;
ret = lstat( path, st );
if (ret == -1) return ret;
if (S_ISLNK( st->st_mode ))
@@ -2566,8 +2568,6 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
+ *attr |= FILE_ATTRIBUTE_HIDDEN;
/* retrieve any stored DOS attributes */
len = xattr_get( path, SAMBA_XATTR_DOS_ATTRIB, hexattr, sizeof(hexattr)-1 );
if (len == -1) return ret;
@@ -2578,8 +2581,6 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
info->AllocationSize = std.AllocationSize;
info->EndOfFile = std.EndOfFile;
info->FileAttributes = basic.FileAttributes;
@ -85,12 +70,12 @@ index 6c278eb..91f96ee 100644
}
RtlFreeAnsiString( &unix_name );
}
@@ -2595,11 +2595,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
@@ -2607,11 +2608,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
status = STATUS_INVALID_INFO_CLASS;
else
- {
status = fill_file_info( xattr, &st, info, FileBasicInformation );
status = fill_file_info( attributes, &st, info, FileBasicInformation );
- if (DIR_is_hidden_file( attr->ObjectName ))
- info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
- }
@ -98,11 +83,11 @@ index 6c278eb..91f96ee 100644
}
else WARN("%s not found (%x)\n", debugstr_us(attr->ObjectName), status );
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 226bc85..be07d59 100644
index ae59552..bacadb0 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -152,7 +152,7 @@ extern int get_file_info( const char *path, struct stat *st, ULONG *xattr ) DECL
extern NTSTATUS fill_file_info( ULONG xattr, const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class ) DECLSPEC_HIDDEN;
@@ -153,7 +153,7 @@ extern NTSTATUS fill_file_info( const ULONG attr, const struct stat *st, void *p
FILE_INFORMATION_CLASS class ) DECLSPEC_HIDDEN;
extern NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ) DECLSPEC_HIDDEN;
extern void DIR_init_windows_dir( const WCHAR *windir, const WCHAR *sysdir ) DECLSPEC_HIDDEN;
-extern BOOL DIR_is_hidden_file( const UNICODE_STRING *name ) DECLSPEC_HIDDEN;

View File

@ -1,4 +1,4 @@
From 3ef7e99e837ddc153bc3f608c9e33b4ec4f47d5b Mon Sep 17 00:00:00 2001
From 17d91743f19deb08a6fa0f36212cd8799c6c7270 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 20:56:49 -0700
Subject: ntdll: Add support for junction point creation.
@ -11,7 +11,7 @@ Subject: ntdll: Add support for junction point creation.
create mode 100644 include/ntifs.h
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 91f96ee..f56facd 100644
index 7b72876..14288b5 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -89,12 +89,14 @@
@ -29,7 +29,7 @@ index 91f96ee..f56facd 100644
#define SECSPERDAY 86400
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY)
@@ -1576,6 +1578,76 @@ NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE handle, HANDLE event,
@@ -1607,6 +1609,76 @@ NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE handle, HANDLE event,
}
@ -106,7 +106,7 @@ index 91f96ee..f56facd 100644
/**************************************************************************
* NtFsControlFile [NTDLL.@]
* ZwFsControlFile [NTDLL.@]
@@ -1723,6 +1795,23 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
@@ -1754,6 +1826,23 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
}
break;
}

View File

@ -1,4 +1,4 @@
From 3870b0d2c6309e4aa93922d8af21ae32ddcf5652 Mon Sep 17 00:00:00 2001
From cb47f74a659bd5447ecbf65591962af6a753dda9 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 20:57:57 -0700
Subject: ntdll: Add support for reading junction points.
@ -9,10 +9,10 @@ Subject: ntdll: Add support for reading junction points.
2 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index f56facd..b02fe76 100644
index 14288b5..b1b8f51 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1648,6 +1648,60 @@ cleanup:
@@ -1679,6 +1679,60 @@ cleanup:
}
@ -73,7 +73,7 @@ index f56facd..b02fe76 100644
/**************************************************************************
* NtFsControlFile [NTDLL.@]
* ZwFsControlFile [NTDLL.@]
@@ -1796,6 +1850,15 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
@@ -1827,6 +1881,15 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
break;
}

View File

@ -1,4 +1,4 @@
From 87bd79756bb80f37751ea79a449e70bad0a08465 Mon Sep 17 00:00:00 2001
From c0100e76f61a689e86c660a056ab30f19749a7b1 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:00:21 -0700
Subject: ntdll: Add support for deleting junction points.
@ -10,10 +10,10 @@ Subject: ntdll: Add support for deleting junction points.
3 files changed, 85 insertions(+)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index b02fe76..682e2e8 100644
index b1b8f51..4b76d04 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1702,6 +1702,41 @@ cleanup:
@@ -1733,6 +1733,41 @@ cleanup:
}
@ -55,7 +55,7 @@ index b02fe76..682e2e8 100644
/**************************************************************************
* NtFsControlFile [NTDLL.@]
* ZwFsControlFile [NTDLL.@]
@@ -1850,6 +1885,22 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
@@ -1881,6 +1916,22 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
break;
}

View File

@ -0,0 +1,28 @@
From 302be7aee826e9876d79be36a596692bac5331d1 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:01:25 -0700
Subject: ntdll: Add a test for junction point advertisement.
---
dlls/ntdll/tests/file.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index cc241c8..3f1973c 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -2770,6 +2770,11 @@ static void test_junction_points(void)
bret = DeviceIoControl(hJunction, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError());
+ /* Check the file attributes of the junction point */
+ dwret = GetFileAttributesW(junction_path);
+ ok(dwret != (DWORD)~0, "Junction point doesn't exist (attributes: 0x%x)!\n", dwret);
+ ok(dwret & FILE_ATTRIBUTE_REPARSE_POINT, "File is not a junction point! (attributes: %d)\n", dwret);
+
/* Read back the junction point */
HeapFree(GetProcessHeap(), 0, buffer);
buffer_len = sizeof(*buffer) + MAX_PATH*sizeof(WCHAR);
--
1.7.9.5

View File

@ -1,62 +0,0 @@
From 624df21e36009121bf5d7ecab86fb0ace8ca15d7 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:01:25 -0700
Subject: ntdll: Advertise that a file is a junction point.
---
dlls/ntdll/file.c | 7 +++++--
dlls/ntdll/tests/file.c | 5 +++++
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 682e2e8..3230d95 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -182,8 +182,8 @@ int get_file_info( const char *path, struct stat *st, ULONG *xattr )
if (S_ISLNK( st->st_mode ))
{
ret = stat( path, st );
+ st->st_mode |= S_IFLNK;
if (ret == -1) return ret;
- if (S_ISDIR( st->st_mode )) *xattr |= FILE_ATTRIBUTE_REPARSE_POINT;
}
len = xattr_get( path, SAMBA_XATTR_DOS_ATTRIB, hexattr, sizeof(hexattr)-1 );
if (len == -1) return ret;
@@ -2088,7 +2088,7 @@ static inline ULONG get_file_attributes( const ULONG xattr, const struct stat *s
{
ULONG attr;
- if (S_ISDIR(st->st_mode))
+ if (st->st_mode & S_IFDIR)
attr = FILE_ATTRIBUTE_DIRECTORY;
else
attr = FILE_ATTRIBUTE_ARCHIVE;
@@ -2098,6 +2098,9 @@ static inline ULONG get_file_attributes( const ULONG xattr, const struct stat *s
if (!(st->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
attr |= FILE_ATTRIBUTE_READONLY;
+
+ if (st->st_mode & S_IFLNK)
+ attr |= FILE_ATTRIBUTE_REPARSE_POINT;
return attr;
}
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index cc241c8..3f1973c 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -2770,6 +2770,11 @@ static void test_junction_points(void)
bret = DeviceIoControl(hJunction, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError());
+ /* Check the file attributes of the junction point */
+ dwret = GetFileAttributesW(junction_path);
+ ok(dwret != (DWORD)~0, "Junction point doesn't exist (attributes: 0x%x)!\n", dwret);
+ ok(dwret & FILE_ATTRIBUTE_REPARSE_POINT, "File is not a junction point! (attributes: %d)\n", dwret);
+
/* Read back the junction point */
HeapFree(GetProcessHeap(), 0, buffer);
buffer_len = sizeof(*buffer) + MAX_PATH*sizeof(WCHAR);
--
1.7.9.5

View File

@ -1,4 +1,4 @@
From e5c5d522bdf363ef1b07e7d18e73ddc2f7ff9305 Mon Sep 17 00:00:00 2001
From 0d309d17751b6bf821b449ba890b5c3465c495a8 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:02:11 -0700
Subject: kernel32,ntdll: Add support for deleting junction points with

View File

@ -1,4 +1,4 @@
From 38d297f6be2c232433e9093ecbfcc45b2de715d2 Mon Sep 17 00:00:00 2001
From a7ca946b7bf408aeb905cb2f5dda782634566d83 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:03:47 -0700
Subject: kernel32: Advertise junction point support.

View File

@ -1,4 +1,4 @@
From 1a343f1a7d57ed717c07026091bca8efe47a8fd6 Mon Sep 17 00:00:00 2001
From 07e1f990c05bc2b82d2c579ce6a57ee2e24852b5 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:06:24 -0700
Subject: ntdll/tests: Add test for deleting junction point target.

View File

@ -0,0 +1,69 @@
From dc4f6f3e4ad3cd249872a297baca22370cc3267d Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:07:43 -0700
Subject: ntdll: Use relative paths for creating links.
---
dlls/ntdll/file.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 4b76d04..b42b4ef 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1624,6 +1624,7 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
int dest_fd, needs_close;
UNICODE_STRING nt_dest;
NTSTATUS status;
+ char *p;
if ((status = server_get_unix_fd( handle, FILE_SPECIAL_ACCESS, &dest_fd, &needs_close, NULL, NULL )))
return status;
@@ -1637,6 +1638,44 @@ NTSTATUS FILE_CreateSymlink(HANDLE handle, REPARSE_DATA_BUFFER *buffer)
goto cleanup;
dest_allocated = TRUE;
+ p = strstr(unix_src.Buffer, "/dosdevices/");
+ if (p)
+ {
+ int count = -1; /* do not count the slash at the end of dosdevices or the last directory */
+
+ p += 11; /* strlen("/dosdevices") */
+ do
+ {
+ p++; /* skip the slash */
+ count++;
+ p = strchr(p, '/');
+ } while(p);
+ FIXME("found %d directories up.\n", count);
+ p = strstr(unix_dest.Buffer, "/dosdevices/");
+ if (p)
+ {
+ ANSI_STRING tmp;
+ int dest_len;
+ char *d;
+
+ p += 12; /* strlen("/dosdevices/") */
+ dest_len = unix_dest.Length - (p-unix_dest.Buffer) + 1;
+ tmp.Length = dest_len + 3*count; /* strlen("../") = 3 */
+ tmp.Buffer = RtlAllocateHeap(GetProcessHeap(), 0, tmp.Length);
+ d = tmp.Buffer;
+ for(; count > 0; count--)
+ {
+ (d++)[0] = '.';
+ (d++)[0] = '.';
+ (d++)[0] = '/';
+ }
+ memcpy(d, p, dest_len);
+ RtlFreeAnsiString( &unix_dest );
+ unix_dest.Length = tmp.Length;
+ unix_dest.Buffer = tmp.Buffer;
+ }
+ }
+
TRACE("Linking %s to %s\n", unix_src.Buffer, unix_dest.Buffer);
/* Produce the link in a temporary location */
--
1.7.9.5