From 4635b6ebd8eba1a7755f985db509aff8c3c06859 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 3 Jul 2006 18:30:08 +0000 Subject: * 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. --- winsup/cygwin/ChangeLog | 24 +++ winsup/cygwin/autoload.cc | 2 + winsup/cygwin/fhandler.cc | 6 +- winsup/cygwin/ntdll.h | 20 +++ winsup/cygwin/ntea.cc | 397 ++++++++++++++-------------------------------- winsup/cygwin/path.cc | 39 +++-- winsup/cygwin/security.cc | 7 +- winsup/cygwin/security.h | 6 +- 8 files changed, 199 insertions(+), 302 deletions(-) (limited to 'winsup/cygwin') 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 + + * 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 * 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 #include +#include #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 ()). */ -- cgit v1.2.3