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-07-03 22:30:08 +0400
committerCorinna Vinschen <corinna@vinschen.de>2006-07-03 22:30:08 +0400
commit4635b6ebd8eba1a7755f985db509aff8c3c06859 (patch)
treefe36a0121e6056888f98cebead9103ea32d012b4 /winsup
parente60e8d3b0ee8b75f3833ba804e385b935b0f4440 (diff)
* autoload.cc (NtQueryEaFile): Define.
(NtSetEaFile): Define. * fhandler.cc (fhandler_base::open): Use appropriate open flags in query case when allow_ntea is set. * ntdll.h (struct _FILE_GET_EA_INFORMATION): Define. (struct _FILE_FULL_EA_INFORMATION): Define. (NtQueryEaFile): Declare. (NtSetEaFile): Declare. * ntea.cc (read_ea): Rename from NTReadEA and rewrite using NtQueryEaFile. (write_ea): Rename from NTWriteEA and rewrite using NtSetEaFile. * path.cc (get_symlink_ea): Make static. Add handle parameter to accomodate new read_ea call. (set_symlink_ea): Make static. Add handle parameter to accomodate new write_ea call. (symlink_worker): Call set_symlink_ea while file is still open. (symlink_info::check): Call get_symlink_ea after file has been opened. * security.cc (get_file_attribute): Accomodate new read_ea call. (set_file_attribute): Accomodate new write_ea call. * security.h (read_ea): Change declaration accordingly. (write_ea): Ditto.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog24
-rw-r--r--winsup/cygwin/autoload.cc2
-rw-r--r--winsup/cygwin/fhandler.cc6
-rw-r--r--winsup/cygwin/ntdll.h20
-rw-r--r--winsup/cygwin/ntea.cc397
-rw-r--r--winsup/cygwin/path.cc39
-rw-r--r--winsup/cygwin/security.cc7
-rw-r--r--winsup/cygwin/security.h6
8 files changed, 199 insertions, 302 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index f158ada06..8d6559f3d 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,27 @@
+2006-07-03 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.cc (NtQueryEaFile): Define.
+ (NtSetEaFile): Define.
+ * fhandler.cc (fhandler_base::open): Use appropriate open flags
+ in query case when allow_ntea is set.
+ * ntdll.h (struct _FILE_GET_EA_INFORMATION): Define.
+ (struct _FILE_FULL_EA_INFORMATION): Define.
+ (NtQueryEaFile): Declare.
+ (NtSetEaFile): Declare.
+ * ntea.cc (read_ea): Rename from NTReadEA and rewrite using
+ NtQueryEaFile.
+ (write_ea): Rename from NTWriteEA and rewrite using NtSetEaFile.
+ * path.cc (get_symlink_ea): Make static. Add handle parameter to
+ accomodate new read_ea call.
+ (set_symlink_ea): Make static. Add handle parameter to accomodate new
+ write_ea call.
+ (symlink_worker): Call set_symlink_ea while file is still open.
+ (symlink_info::check): Call get_symlink_ea after file has been opened.
+ * security.cc (get_file_attribute): Accomodate new read_ea call.
+ (set_file_attribute): Accomodate new write_ea call.
+ * security.h (read_ea): Change declaration accordingly.
+ (write_ea): Ditto.
+
2006-07-03 Kazuhiro Fujieda <fujieda@jaist.ac.jp>
* fhandler.h (class dev_console): Add `metabit' indicating the
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index c6ce11317..25c7dd84f 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -392,6 +392,7 @@ LoadDLLfuncNt (NtOpenFile, 24, ntdll)
LoadDLLfuncNt (NtOpenSection, 12, ntdll)
LoadDLLfuncNt (NtQueryDirectoryObject, 28, ntdll)
LoadDLLfuncNt (NtQueryDirectoryFile, 44, ntdll)
+LoadDLLfuncNt (NtQueryEaFile, 36, ntdll)
LoadDLLfuncNt (NtQueryInformationFile, 20, ntdll)
LoadDLLfuncNt (NtQueryInformationProcess, 20, ntdll)
LoadDLLfuncNt (NtQueryObject, 20, ntdll)
@@ -399,6 +400,7 @@ LoadDLLfuncNt (NtQuerySystemInformation, 16, ntdll)
LoadDLLfuncNt (NtQuerySecurityObject, 20, ntdll)
LoadDLLfuncNt (NtQueryVirtualMemory, 24, ntdll)
LoadDLLfuncNt (NtQueryVolumeInformationFile, 20, ntdll)
+LoadDLLfuncNt (NtSetEaFile, 16, ntdll)
LoadDLLfuncNt (NtSetSecurityObject, 12, ntdll)
LoadDLLfuncNt (NtUnlockVirtualMemory, 16, ntdll)
LoadDLLfuncNt (NtUnmapViewOfSection, 8, ntdll)
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index a48f3d91a..50bde0064 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -590,11 +590,13 @@ fhandler_base::open (int flags, mode_t mode)
create_options = FILE_OPEN_FOR_BACKUP_INTENT;
break;
case query_stat_control:
- access = READ_CONTROL | FILE_READ_ATTRIBUTES | FILE_READ_DATA;
+ access = READ_CONTROL | FILE_READ_ATTRIBUTES
+ | (allow_ntea ? FILE_READ_EA : 0);
create_options = FILE_OPEN_FOR_BACKUP_INTENT;
break;
case query_write_control:
- access = READ_CONTROL | WRITE_OWNER | WRITE_DAC | FILE_WRITE_ATTRIBUTES;
+ access = READ_CONTROL | WRITE_OWNER | WRITE_DAC | FILE_WRITE_ATTRIBUTES
+ | (allow_ntea ? FILE_WRITE_EA : 0);
create_options = FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_FOR_RECOVERY;
break;
case query_write_attributes:
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index ff5f0c93a..2a71cd8f6 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -581,6 +581,23 @@ typedef struct _DIRECTORY_BASIC_INFORMATION
UNICODE_STRING ObjectTypeName;
} DIRECTORY_BASIC_INFORMATION, *PDIRECTORY_BASIC_INFORMATION;
+typedef struct _FILE_GET_EA_INFORMATION
+{
+ ULONG NextEntryOffset;
+ UCHAR EaNameLength;
+ CHAR EaName[1];
+} FILE_GET_EA_INFORMATION, *PFILE_GET_EA_INFORMATION;
+
+
+typedef struct _FILE_FULL_EA_INFORMATION
+{
+ ULONG NextEntryOffset;
+ UCHAR Flags;
+ UCHAR EaNameLength;
+ USHORT EaValueLength;
+ CHAR EaName[1];
+} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
+
/* Function declarations for ntdll.dll. These don't appear in any
standard Win32 header. */
extern "C"
@@ -611,6 +628,8 @@ extern "C"
PUNICODE_STRING, BOOLEAN);
NTSTATUS NTAPI NtQueryDirectoryObject (HANDLE, PVOID, ULONG, BOOLEAN,
BOOLEAN, PULONG, PULONG);
+ NTSTATUS NTAPI NtQueryEaFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG,
+ BOOLEAN, PVOID, ULONG, PULONG, BOOLEAN);
NTSTATUS NTAPI NtQueryInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,
ULONG, FILE_INFORMATION_CLASS);
NTSTATUS NTAPI NtQueryInformationProcess (HANDLE, PROCESSINFOCLASS,
@@ -626,6 +645,7 @@ extern "C"
NTSTATUS NTAPI NtQueryVolumeInformationFile (HANDLE, IO_STATUS_BLOCK *,
VOID *, ULONG,
FS_INFORMATION_CLASS);
+ NTSTATUS NTAPI NtSetEaFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG);
NTSTATUS NTAPI NtSetSecurityObject (HANDLE, SECURITY_INFORMATION,
PSECURITY_DESCRIPTOR);
NTSTATUS NTAPI NtUnlockVirtualMemory (HANDLE, PVOID *, ULONG *, ULONG);
diff --git a/winsup/cygwin/ntea.cc b/winsup/cygwin/ntea.cc
index f33d82250..72463feb0 100644
--- a/winsup/cygwin/ntea.cc
+++ b/winsup/cygwin/ntea.cc
@@ -1,6 +1,6 @@
/* ntea.cc: code for manipulating NTEA information
- Copyright 1997, 1998, 2000, 2001 Red Hat, Inc.
+ Copyright 1997, 1998, 2000, 2001, 2006 Red Hat, Inc.
Written by Sergey S. Okhapkin (sos@prospect.com.ru)
@@ -11,315 +11,162 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
-#include <stdio.h>
#include <stdlib.h>
+#include <ntdef.h>
#include "security.h"
+#include "ntdll.h"
/* Default to not using NTEA information */
bool allow_ntea;
/*
-From Windows NT DDK:
-
-FILE_FULL_EA_INFORMATION provides extended attribute information.
-This structure is used primarily by network drivers.
-
-Members
-
-NextEntryOffset
-The offset of the next FILE_FULL_EA_INFORMATION-type entry. This member is
-zero if no other entries follow this one.
-
-Flags
-Can be zero or can be set with FILE_NEED_EA, indicating that the file to which
-the EA belongs cannot be interpreted without understanding the associated
-extended attributes.
-
-EaNameLength
-The length in bytes of the EaName array. This value does not include a
-zero-terminator to EaName.
-
-EaValueLength
-The length in bytes of each EA value in the array.
-
-EaName
-An array of characters naming the EA for this entry.
-
-Comments
-This structure is longword-aligned. If a set of FILE_FULL_EA_INFORMATION
-entries is buffered, NextEntryOffset value in each entry, except the last,
-falls on a longword boundary.
-The value(s) associated with each entry follows the EaName array. That is, an
-EA's values are located at EaName + (EaNameLength + 1).
-*/
-
-typedef struct _FILE_FULL_EA_INFORMATION {
- ULONG NextEntryOffset;
- UCHAR Flags;
- UCHAR EaNameLength;
- USHORT EaValueLength;
- CHAR EaName[1];
-} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
-
-/* Functions prototypes */
-
-int NTReadEA (const char *file, const char *attrname, char *buf, int len);
-static PFILE_FULL_EA_INFORMATION NTReadEARaw (HANDLE file, int *len);
-BOOL NTWriteEA(const char *file, const char *attrname, char *buf, int len);
-
-/*
- * NTReadEA - read file's Extended Attribute.
+ * read_ea - read file's Extended Attribute.
*
* Parameters:
* file - pointer to filename
- * attrname- pointer to EA name (case insensitivy. EAs are sored in upper
- * case).
+ * attrname- pointer to EA name (case insensitiv)
* attrbuf - pointer to buffer to store EA's value.
* len - length of attrbuf.
* Return value:
* 0 - if file or attribute "attrname" not found.
- * N - number of bytes stored in attrbuf if succes.
+ * N - number of bytes stored in attrbuf if success.
* -1 - attrbuf too small for EA value.
*/
int __stdcall
-NTReadEA (const char *file, const char *attrname, char *attrbuf, int len)
-{
- HANDLE hFileSource;
- int eafound = 0;
- PFILE_FULL_EA_INFORMATION ea, sea;
- int easize = 0;
-
- hFileSource = CreateFile (file, FILE_READ_EA,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- &sec_none_nih, // sa
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS,
- NULL);
-
- if (hFileSource == INVALID_HANDLE_VALUE)
- return 0;
-
- /* Read in raw array of EAs */
- ea = sea = NTReadEARaw (hFileSource, &easize);
-
- /* Search for requested attribute */
- while (sea)
- {
- if (strcasematch (ea->EaName, attrname)) /* EA found */
- {
- if (ea->EaValueLength > len)
- {
- eafound = -1; /* buffer too small */
- break;
- }
- memcpy (attrbuf, ea->EaName + (ea->EaNameLength + 1),
- ea->EaValueLength);
- eafound = ea->EaValueLength;
- break;
- }
- if ((ea->NextEntryOffset == 0) || ((int) ea->NextEntryOffset > easize))
- break;
- ea = (PFILE_FULL_EA_INFORMATION) ((char *) ea + ea->NextEntryOffset);
- }
-
- if (sea)
- free (sea);
- CloseHandle (hFileSource);
-
- return eafound;
-}
-
-/*
- * NTReadEARaw - internal routine to read EAs array to malloced buffer. The
- * caller should free this buffer after usage.
- * Parameters:
- * hFileSource - handle to file. This handle should have FILE_READ_EA
- * rights.
- * len - pointer to int variable where length of buffer will
- * be stored.
- * Return value:
- * pointer to buffer with file's EAs, or NULL if any error occured.
- */
-
-static PFILE_FULL_EA_INFORMATION
-NTReadEARaw (HANDLE hFileSource, int *len)
+read_ea (HANDLE hdl, const char *file, const char *attrname, char *attrbuf,
+ int len)
{
- WIN32_STREAM_ID StreamId;
- DWORD dwBytesWritten;
- LPVOID lpContext;
- DWORD StreamSize;
- PFILE_FULL_EA_INFORMATION eafound = NULL;
-
- lpContext = NULL;
- StreamSize = sizeof (WIN32_STREAM_ID) - sizeof (WCHAR**);
-
- /* Read the WIN32_STREAM_ID in */
-
- while (BackupRead (hFileSource, (LPBYTE) &StreamId, StreamSize,
- &dwBytesWritten,
- FALSE, // don't abort yet
- FALSE, // don't process security
- &lpContext))
+ IO_STATUS_BLOCK io;
+
+ /* Prepare buffer which receives the result. */
+ ULONG flen = sizeof (FILE_FULL_EA_INFORMATION) + strlen (attrname)
+ + len + 1;
+ PFILE_FULL_EA_INFORMATION fea = (PFILE_FULL_EA_INFORMATION) alloca (flen);
+ /* Prepare buffer specifying the EA to search for. */
+ ULONG glen = sizeof (FILE_GET_EA_INFORMATION) + strlen (attrname);
+ PFILE_GET_EA_INFORMATION gea = (PFILE_GET_EA_INFORMATION) alloca (glen);
+ gea->NextEntryOffset = 0;
+ gea->EaNameLength = strlen (attrname);
+ strcpy (gea->EaName, attrname);
+
+ /* If no incoming hdl is given, the loop only runs once, trying to
+ open the file and to query the EA. If an incoming hdl is given,
+ the loop runs twice, first trying to query with the given hdl.
+ If this fails it tries to open the file and to query with that
+ handle again. */
+ HANDLE h = hdl;
+ NTSTATUS status = STATUS_SUCCESS;
+ int ret = 0;
+ while (true)
{
- DWORD sl,sh;
-
- if (dwBytesWritten == 0) /* No more Stream IDs */
- break;
- /* skip StreamName */
- if (StreamId.dwStreamNameSize)
+ if (!hdl && (h = CreateFile (file, FILE_READ_EA,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ &sec_none_nih, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL))
+ == INVALID_HANDLE_VALUE)
{
- unsigned char *buf;
- buf = (unsigned char *) malloc (StreamId.dwStreamNameSize);
-
- if (buf == NULL)
- break;
-
- if (!BackupRead (hFileSource, buf, // buffer to read
- StreamId.dwStreamNameSize, // num bytes to read
- &dwBytesWritten,
- FALSE, // don't abort yet
- FALSE, // don't process security
- &lpContext)) // Stream name read error
- {
- free (buf);
- break;
- }
- free (buf);
- }
-
- /* Is it EA stream? */
- if (StreamId.dwStreamId == BACKUP_EA_DATA)
- {
- unsigned char *buf;
- buf = (unsigned char *) malloc (StreamId.Size.LowPart);
-
- if (buf == NULL)
- break;
- if (!BackupRead (hFileSource, buf, // buffer to read
- StreamId.Size.LowPart, // num bytes to write
- &dwBytesWritten,
- FALSE, // don't abort yet
- FALSE, // don't process security
- &lpContext))
- {
- free (buf); /* EA read error */
- break;
- }
- eafound = (PFILE_FULL_EA_INFORMATION) buf;
- *len = StreamId.Size.LowPart;
- break;
+ debug_printf ("Opening %s for querying EA %s failed, %E",
+ file, attrname);
+ goto out;
}
- /* Skip current stream */
- if (!BackupSeek (hFileSource,
- StreamId.Size.LowPart,
- StreamId.Size.HighPart,
- &sl,
- &sh,
- &lpContext))
- break;
+ status = NtQueryEaFile (h, &io, fea, flen, FALSE, gea, glen, NULL, TRUE);
+ if (NT_SUCCESS (status) || !hdl)
+ break;
+ debug_printf ("1. chance, %x = NtQueryEaFile (%s, %s), Win32 error %d",
+ status, file, attrname, RtlNtStatusToDosError (status));
+ hdl = NULL;
+ }
+ if (!hdl)
+ CloseHandle (h);
+ if (!NT_SUCCESS (status))
+ {
+ ret = -1;
+ debug_printf ("%x = NtQueryEaFile (%s, %s), Win32 error %d",
+ status, file, attrname, RtlNtStatusToDosError (status));
+ }
+ if (!fea->EaValueLength)
+ ret = 0;
+ else
+ {
+ memcpy (attrbuf, fea->EaName + fea->EaNameLength + 1,
+ fea->EaValueLength);
+ ret = fea->EaValueLength;
}
- /* free context */
- BackupRead (
- hFileSource,
- NULL, // buffer to write
- 0, // number of bytes to write
- &dwBytesWritten,
- TRUE, // abort
- FALSE, // don't process security
- &lpContext);
-
- return eafound;
+out:
+ debug_printf ("%d = read_ea (%x, %s, %s, %x, %d)", ret, hdl, file, attrname,
+ attrbuf, len);
+ return ret;
}
/*
- * NTWriteEA - write file's Extended Attribute.
+ * write_ea - write file's Extended Attribute.
*
* Parameters:
* file - pointer to filename
- * attrname- pointer to EA name (case insensitivy. EAs are sored in upper
- * case).
- * buf - pointer to buffer with EA value.
- * len - length of buf.
+ * attrname- pointer to EA name (case insensitiv)
+ * attrbuf - pointer to buffer with EA value.
+ * len - length of attrbuf.
* Return value:
* true if success, false otherwice.
* Note: if len=0 given EA will be deleted.
*/
BOOL __stdcall
-NTWriteEA (const char *file, const char *attrname, const char *buf, int len)
+write_ea (HANDLE hdl, const char *file, const char *attrname,
+ const char *attrbuf, int len)
{
- HANDLE hFileSource;
- WIN32_STREAM_ID StreamId;
- DWORD dwBytesWritten;
- LPVOID lpContext;
- DWORD StreamSize, easize;
- bool bSuccess = false;
- PFILE_FULL_EA_INFORMATION ea;
-
- hFileSource = CreateFile (file, FILE_WRITE_EA,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- &sec_none_nih, // sa
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS,
- NULL);
-
- if (hFileSource == INVALID_HANDLE_VALUE)
- return FALSE;
-
- lpContext = NULL;
- StreamSize = sizeof (WIN32_STREAM_ID) - sizeof (WCHAR**);
-
- /* FILE_FULL_EA_INFORMATION structure is longword-aligned */
- easize = sizeof (*ea) - sizeof (WCHAR**) + strlen (attrname) + 1 + len
- + (sizeof (DWORD) - 1);
- easize &= ~(sizeof (DWORD) - 1);
-
- if ((ea = (PFILE_FULL_EA_INFORMATION) malloc (easize)) == NULL)
- goto cleanup;
-
- memset (ea, 0, easize);
- ea->EaNameLength = strlen (attrname);
- ea->EaValueLength = len;
- strcpy (ea->EaName, attrname);
- memcpy (ea->EaName + (ea->EaNameLength + 1), buf, len);
-
- StreamId.dwStreamId = BACKUP_EA_DATA;
- StreamId.dwStreamAttributes = 0;
- StreamId.Size.HighPart = 0;
- StreamId.Size.LowPart = easize;
- StreamId.dwStreamNameSize = 0;
-
- if (!BackupWrite (hFileSource, (LPBYTE) &StreamId, StreamSize,
- &dwBytesWritten,
- FALSE, // don't abort yet
- FALSE, // don't process security
- &lpContext))
- goto cleanup;
-
- if (!BackupWrite (hFileSource, (LPBYTE) ea, easize,
- &dwBytesWritten,
- FALSE, // don't abort yet
- FALSE, // don't process security
- &lpContext))
- goto cleanup;
-
- bSuccess = true;
- /* free context */
-
-cleanup:
- BackupRead (hFileSource,
- NULL, // buffer to write
- 0, // number of bytes to write
- &dwBytesWritten,
- TRUE, // abort
- FALSE, // don't process security
- &lpContext);
-
- CloseHandle (hFileSource);
- if (ea)
- free (ea);
-
- return bSuccess;
+ IO_STATUS_BLOCK io;
+
+ /* Prepare buffer specifying the EA to write back. */
+ ULONG flen = sizeof (FILE_FULL_EA_INFORMATION) + strlen (attrname)
+ + len + 1;
+ PFILE_FULL_EA_INFORMATION fea = (PFILE_FULL_EA_INFORMATION) alloca (flen);
+ fea->NextEntryOffset = 0;
+ fea->Flags = 0;
+ fea->EaNameLength = strlen (attrname);
+ fea->EaValueLength = len;
+ strcpy (fea->EaName, attrname);
+ memcpy (fea->EaName + fea->EaNameLength + 1, attrbuf, len);
+
+ /* If no incoming hdl is given, the loop only runs once, trying to
+ open the file and to set the EA. If an incoming hdl is given,
+ the loop runs twice, first trying to set the EA with the given hdl.
+ If this fails it tries to open the file and to set the EA with that
+ handle again. */
+ HANDLE h = hdl;
+ NTSTATUS status = STATUS_SUCCESS;
+ bool ret = false;
+ while (true)
+ {
+ if (!hdl && (h = CreateFile (file, FILE_READ_EA,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ &sec_none_nih, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL))
+ == INVALID_HANDLE_VALUE)
+ {
+ debug_printf ("Opening %s for setting EA %s failed, %E",
+ file, attrname);
+ goto out;
+ }
+ status = NtSetEaFile (h, &io, fea, flen);
+ if (NT_SUCCESS (status) || !hdl)
+ break;
+ debug_printf ("1. chance, %x = NtQueryEaFile (%s, %s), Win32 error %d",
+ status, file, attrname, RtlNtStatusToDosError (status));
+ hdl = NULL;
+ }
+ if (!hdl)
+ CloseHandle (h);
+ if (!NT_SUCCESS (status))
+ debug_printf ("%x = NtQueryEaFile (%s, %s), Win32 error %d",
+ status, file, attrname, RtlNtStatusToDosError (status));
+ else
+ ret = true;
+
+out:
+ debug_printf ("%d = write_ea (%x, %s, %s, %x, %d)", ret, hdl, file, attrname,
+ attrbuf, len);
+ return ret;
}
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index ea96596ef..f9891f5a8 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -2694,20 +2694,20 @@ endmntent (FILE *)
/********************** Symbolic Link Support **************************/
/* Read symlink from Extended Attribute */
-int
-get_symlink_ea (const char* frompath, char* buf, int buf_size)
+static int
+get_symlink_ea (HANDLE hdl, const char* frompath, char* buf, int buf_size)
{
- int res = NTReadEA (frompath, SYMLINK_EA_NAME, buf, buf_size);
+ int res = read_ea (hdl, frompath, SYMLINK_EA_NAME, buf, buf_size);
if (res == 0)
debug_printf ("Cannot read symlink from EA");
return (res - 1);
}
/* Save symlink to Extended Attribute */
-bool
-set_symlink_ea (const char* frompath, const char* topath)
+static bool
+set_symlink_ea (HANDLE hdl, const char* frompath, const char* topath)
{
- if (!NTWriteEA (frompath, SYMLINK_EA_NAME, topath, strlen (topath) + 1))
+ if (!write_ea (hdl, frompath, SYMLINK_EA_NAME, topath, strlen (topath) + 1))
{
debug_printf ("Cannot save symlink in EA");
return false;
@@ -2926,6 +2926,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
}
if (success)
{
+ if (!isdevice && win32_path.fs_has_ea ())
+ set_symlink_ea (h, win32_path, oldpath);
CloseHandle (h);
if (!allow_ntsec && allow_ntea)
set_file_attribute (false, NULL, win32_path.get_win32 (),
@@ -2940,8 +2942,6 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym,
#endif
SetFileAttributes (win32_path, attr);
- if (!isdevice && win32_path.fs_has_ea ())
- set_symlink_ea (win32_path, oldpath);
res = 0;
}
else
@@ -3340,16 +3340,6 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt)
if (!sym_check)
goto file_not_symlink;
- if (sym_check > 0 && opt & PC_CHECK_EA &&
- (res = get_symlink_ea (suffix.path, contents, sizeof (contents))) > 0)
- {
- pflags = PATH_SYMLINK | pflags_or;
- if (sym_check == 1)
- pflags |= PATH_LNK;
- debug_printf ("Got symlink from EA: %s", contents);
- break;
- }
-
/* Open the file. */
h = CreateFile (suffix.path, GENERIC_READ, FILE_SHARE_READ,
@@ -3358,8 +3348,17 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt)
if (h == INVALID_HANDLE_VALUE)
goto file_not_symlink;
- /* FIXME: if symlink isn't present in EA, but EAs are supported,
- should we write it there? */
+ if (sym_check > 0 && opt & PC_CHECK_EA
+ && (res = get_symlink_ea (h, suffix.path, contents,
+ sizeof (contents))) > 0)
+ {
+ pflags = PATH_SYMLINK | pflags_or;
+ if (sym_check == 1)
+ pflags |= PATH_LNK;
+ debug_printf ("Got symlink from EA: %s", contents);
+ break;
+ }
+
switch (sym_check)
{
case 1:
diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc
index 8a994fe80..23f86e369 100644
--- a/winsup/cygwin/security.cc
+++ b/winsup/cygwin/security.cc
@@ -1405,7 +1405,8 @@ get_file_attribute (int use_ntsec, HANDLE handle, const char *file,
if (allow_ntea)
{
int oatt = *attribute;
- res = NTReadEA (file, ".UNIXATTR", (char *)attribute, sizeof (*attribute));
+ res = read_ea (handle, file, ".UNIXATTR", (char *)attribute,
+ sizeof (*attribute));
*attribute |= oatt;
}
else
@@ -1801,8 +1802,8 @@ set_file_attribute (bool use_ntsec, HANDLE handle, const char *file,
if (use_ntsec && allow_ntsec)
ret = set_nt_attribute (handle, file, uid, gid, attribute);
- else if (allow_ntea && !NTWriteEA (file, ".UNIXATTR", (char *) &attribute,
- sizeof (attribute)))
+ else if (allow_ntea && !write_ea (handle, file, ".UNIXATTR",
+ (char *) &attribute, sizeof (attribute)))
{
__seterrno ();
ret = -1;
diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h
index ec53dfc23..a55cc03d6 100644
--- a/winsup/cygwin/security.h
+++ b/winsup/cygwin/security.h
@@ -378,8 +378,10 @@ extern SECURITY_ATTRIBUTES *__stdcall __sec_user (PVOID sa_buf, PSID sid1, PSID
extern bool sec_acl (PACL acl, bool original, bool admins, PSID sid1 = NO_SID,
PSID sid2 = NO_SID, DWORD access2 = 0);
-int __stdcall NTReadEA (const char *file, const char *attrname, char *buf, int len);
-BOOL __stdcall NTWriteEA (const char *file, const char *attrname, const char *buf, int len);
+int __stdcall read_ea (HANDLE hdl, const char *file, const char *attrname,
+ char *buf, int len);
+BOOL __stdcall write_ea (HANDLE hdl, const char *file, const char *attrname,
+ const char *buf, int len);
/* Note: sid1 is usually (read: currently always) the current user's
effective sid (cygheap->user.sid ()). */