Skip to content

Commit

Permalink
Merge branch 'better-onedrive-support'
Browse files Browse the repository at this point in the history
This topic branch backports the improvements of Cygwin where it no
longer tries to download file contents from OneDrive just to list the
directory contents including faked executable permissions.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
  • Loading branch information
dscho committed Jul 9, 2024
2 parents 4eb0db9 + 59d7115 commit 2e2ef94
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 14 deletions.
1 change: 1 addition & 0 deletions winsup/cygwin/autoload.cc
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,7 @@ LoadDLLfuncEx (SetThreadDescription, 8, KernelBase, 1)
LoadDLLfunc (VirtualAlloc2, 28, KernelBase)

LoadDLLfunc (NtMapViewOfSectionEx, 36, ntdll)
LoadDLLfuncEx (RtlSetProcessPlaceholderCompatibilityMode, 4, ntdll, 1)

LoadDLLfunc (ldap_bind_s, 0, wldap32)
LoadDLLfunc (ldap_count_entries, 0, wldap32)
Expand Down
3 changes: 3 additions & 0 deletions winsup/cygwin/dcrt0.cc
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,9 @@ dll_crt0_1 (void *)
if (dynamically_loaded)
sigproc_init ();

/* Call this before accessing any files. */
RtlSetProcessPlaceholderCompatibilityMode (PHCM_EXPOSE_PLACEHOLDERS);

check_sanity_and_sync (user_data);

/* Initialize malloc and then call user_shared_initialize since it relies
Expand Down
19 changes: 13 additions & 6 deletions winsup/cygwin/fhandler/disk_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,9 @@ readdir_check_reparse_point (POBJECT_ATTRIBUTES attr, bool remote)
bool ret = false;

status = NtOpenFile (&reph, READ_CONTROL, attr, &io, FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT);
FILE_OPEN_NO_RECALL
| FILE_OPEN_FOR_BACKUP_INTENT
| FILE_OPEN_REPARSE_POINT);
if (NT_SUCCESS (status))
{
PREPARSE_DATA_BUFFER rp = (PREPARSE_DATA_BUFFER) tp.c_get ();
Expand Down Expand Up @@ -609,7 +611,8 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
opened = NT_SUCCESS (NtOpenFile (&fh, READ_CONTROL,
pc.get_object_attr (attr, sec_none_nih),
&io, FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT));
FILE_OPEN_NO_RECALL
| FILE_OPEN_FOR_BACKUP_INTENT));
if (!opened)
{
/* Can't open file. Try again with parent dir. */
Expand All @@ -618,7 +621,8 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
attr.ObjectName = &dirname;
opened = NT_SUCCESS (NtOpenFile (&fh, READ_CONTROL, &attr, &io,
FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT));
FILE_OPEN_NO_RECALL
| FILE_OPEN_FOR_BACKUP_INTENT));
if (!opened)
goto out;
}
Expand Down Expand Up @@ -2054,7 +2058,8 @@ readdir_get_ino (const char *path, bool dot_dot)
|| NT_SUCCESS (NtOpenFile (&hdl, READ_CONTROL,
pc.get_object_attr (attr, sec_none_nih),
&io, FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT
FILE_OPEN_NO_RECALL
| FILE_OPEN_FOR_BACKUP_INTENT
| (pc.is_known_reparse_point ()
? FILE_OPEN_REPARSE_POINT : 0)))
)
Expand Down Expand Up @@ -2103,8 +2108,9 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
Mountpoints and unknown or unhandled reparse points will be treated
as normal file/directory/unknown. In all cases, returning the INO of
the reparse point (not of the target) matches behavior of posix systems.
Unless the file is OFFLINE. *.
*/
if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) && !isoffline (attr))
{
OBJECT_ATTRIBUTES oattr;

Expand Down Expand Up @@ -2345,7 +2351,8 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
&nfs_aol_ffei, sizeof nfs_aol_ffei)
: NtOpenFile (&hdl, READ_CONTROL, &attr, &io,
FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT
FILE_OPEN_NO_RECALL
| FILE_OPEN_FOR_BACKUP_INTENT
| FILE_OPEN_REPARSE_POINT);
if (NT_SUCCESS (f_status))
{
Expand Down
8 changes: 8 additions & 0 deletions winsup/cygwin/local_includes/ntdll.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,13 @@ extern GUID __cygwin_socket_guid;
#define FILE_VC_QUOTAS_REBUILDING 0x00000200
#define FILE_VC_VALID_MASK 0x000003ff

#define PHCM_APPLICATION_DEFAULT 0
#define PHCM_DISGUISE_PLACEHOLDER 1
#define PHCM_EXPOSE_PLACEHOLDERS 2
#define PHCM_MAX 2
#define PHCM_ERROR_INVALID_PARAMETER -1
#define PHCM_ERROR_NO_TEB -2

/* IOCTL code to impersonate client of named pipe. */

#define FSCTL_PIPE_DISCONNECT CTL_CODE(FILE_DEVICE_NAMED_PIPE, 1, \
Expand Down Expand Up @@ -1605,6 +1612,7 @@ extern "C"
BOOLEAN);
NTSTATUS RtlSetGroupSecurityDescriptor (PSECURITY_DESCRIPTOR, PSID, BOOLEAN);
NTSTATUS RtlSetOwnerSecurityDescriptor (PSECURITY_DESCRIPTOR, PSID, BOOLEAN);
CHAR RtlSetProcessPlaceholderCompatibilityMode (CHAR);
PUCHAR RtlSubAuthorityCountSid (PSID);
PULONG RtlSubAuthoritySid (PSID, ULONG);
ULONG RtlUnicodeStringToAnsiSize (PUNICODE_STRING);
Expand Down
16 changes: 15 additions & 1 deletion winsup/cygwin/local_includes/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ has_attribute (DWORD attributes, DWORD attribs_to_test)
&& (attributes & attribs_to_test);
}

extern inline bool
isoffline (DWORD attributes)
{
return has_attribute (attributes, FILE_ATTRIBUTE_OFFLINE
| FILE_ATTRIBUTE_RECALL_ON_OPEN
| FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS);
}

enum executable_states
{
is_executable,
Expand Down Expand Up @@ -230,14 +238,20 @@ class path_conv
bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;}
bool has_attribute (DWORD x) const {return exists () && (fileattr & x);}
int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}
bool isoffline () const
{
return has_attribute (FILE_ATTRIBUTE_OFFLINE
| FILE_ATTRIBUTE_RECALL_ON_OPEN
| FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS);
}
executable_states exec_state ()
{
extern int _check_for_executable;
if (mount_flags & (MOUNT_CYGWIN_EXEC | MOUNT_EXEC))
return is_executable;
if (mount_flags & MOUNT_NOTEXEC)
return not_executable;
if (!_check_for_executable)
if (isoffline () || !_check_for_executable)
return dont_care_if_executable;
return dont_know_if_executable;
}
Expand Down
8 changes: 8 additions & 0 deletions winsup/cygwin/local_includes/winlean.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ details. */
#undef CRITICAL
#endif

/* Filesystem flags not yet supported by Mingw-w64 headers. */
#ifndef FILE_ATTRIBUTE_RECALL_ON_OPEN
#define FILE_ATTRIBUTE_RECALL_ON_OPEN 0x00040000
#endif
#ifndef FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS
#define FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS 0x00400000
#endif

/* So-called "Microsoft Account" SIDs (S-1-11-...) have a netbios domain name
"MicrosoftAccounts". The new "Application Container SIDs" (S-1-15-...)
have a netbios domain name "APPLICATION PACKAGE AUTHORITY"
Expand Down
15 changes: 11 additions & 4 deletions winsup/cygwin/path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3378,7 +3378,8 @@ symlink_info::check (char *path, const suffix_info *suffixes, fs_info &fs,
}
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_ATTRIBUTES,
&attr, &io, FILE_SHARE_VALID_FLAGS,
FILE_OPEN_REPARSE_POINT
FILE_OPEN_NO_RECALL
| FILE_OPEN_REPARSE_POINT
| FILE_OPEN_FOR_BACKUP_INTENT);
debug_printf ("%y = NtOpenFile (no-EAs %S)", status, &upath);
}
Expand Down Expand Up @@ -3595,7 +3596,11 @@ symlink_info::check (char *path, const suffix_info *suffixes, fs_info &fs,
directory using a relative path, symlink evaluation goes totally
awry. We never want a virtual drive evaluated as symlink. */
if (upath.Length <= 14)
goto file_not_symlink;
goto file_not_symlink;

/* Offline files, even if reparse points, are not symlinks. */
if (isoffline (fileattr))
goto file_not_symlink;

/* Reparse points are potentially symlinks. This check must be
performed before checking the SYSTEM attribute for sysfile
Expand Down Expand Up @@ -3641,7 +3646,8 @@ symlink_info::check (char *path, const suffix_info *suffixes, fs_info &fs,

status = NtOpenFile (&sym_h, SYNCHRONIZE | GENERIC_READ, &attr, &io,
FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT
FILE_OPEN_NO_RECALL
| FILE_OPEN_FOR_BACKUP_INTENT
| FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS (status))
res = 0;
Expand Down Expand Up @@ -3685,7 +3691,8 @@ symlink_info::check (char *path, const suffix_info *suffixes, fs_info &fs,

status = NtOpenFile (&sym_h, SYNCHRONIZE | GENERIC_READ, &attr, &io,
FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT
FILE_OPEN_NO_RECALL
| FILE_OPEN_FOR_BACKUP_INTENT
| FILE_SYNCHRONOUS_IO_NONALERT);

if (!NT_SUCCESS (status))
Expand Down
9 changes: 6 additions & 3 deletions winsup/cygwin/sec/base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ get_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd,
fh ? pc.init_reopen_attr (attr, fh)
: pc.get_object_attr (attr, sec_none_nih),
&io, FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT
FILE_OPEN_NO_RECALL
| FILE_OPEN_FOR_BACKUP_INTENT
| pc.is_known_reparse_point ()
? FILE_OPEN_REPARSE_POINT : 0);
if (!NT_SUCCESS (status))
Expand Down Expand Up @@ -129,7 +130,8 @@ get_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd,
NULL, NULL);
status = NtOpenFile (&fh, READ_CONTROL, &attr, &io,
FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT
FILE_OPEN_NO_RECALL
| FILE_OPEN_FOR_BACKUP_INTENT
| FILE_OPEN_REPARSE_POINT);
if (!NT_SUCCESS (status))
{
Expand Down Expand Up @@ -234,7 +236,8 @@ set_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd, bool is_chown)
: pc.get_object_attr (attr, sec_none_nih),
&io,
FILE_SHARE_VALID_FLAGS,
FILE_OPEN_FOR_BACKUP_INTENT
FILE_OPEN_NO_RECALL
| FILE_OPEN_FOR_BACKUP_INTENT
| pc.is_known_reparse_point ()
? FILE_OPEN_REPARSE_POINT : 0);
if (!NT_SUCCESS (status))
Expand Down

0 comments on commit 2e2ef94

Please sign in to comment.