Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support OneDrive better #69

Merged
merged 20 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
da83e4d
Cygwin: try to avoid recalling offline files
github-cygwin Mar 8, 2024
6380bea
Cygwin: get/set security descriptors using FILE_OPEN_NO_RECALL
github-cygwin Mar 8, 2024
59d7115
Cygwin: FILE_OPEN_NO_RECALL is incompatible with FILE_DIRECTORY_FILE
github-cygwin Apr 4, 2024
4b3a2e0
Cygwin: suppress a warning generated with w32api >= 12.0.0
dscho Jul 8, 2024
66bb413
fixup! Allow overriding the home directory via the HOME variable
dscho Nov 29, 2023
94c27b7
fixup! Respect `db_home` setting even for the SYSTEM account
dscho Nov 29, 2023
8f9fcab
fixup! Respect the `db_home: env` setting under more circumstances
dscho Nov 29, 2023
83137f9
Allow deriving the current user's home directory via the HOME variable
dscho Mar 28, 2023
a24bc22
Respect `db_home` setting even for SYSTEM/Microsoft accounts
dscho Apr 3, 2023
27a7508
uinfo: special-case IIS APPPOOL accounts
dscho May 22, 2023
1b8d886
Do not rely on `getenv ("HOME")`'s path conversion
dscho May 22, 2023
91ac9c0
Merge branch 'clean-up-home-env-patches'
dscho Jul 9, 2024
2466162
fixup! CI: fix the build with gcc 13
lazka Dec 22, 2023
7793231
pathconv: don't skip arguments with double quote
lazka Feb 10, 2024
fdc7c9a
Cygwin: console: Fix exit code for non-cygwin process.
tyan0 Feb 2, 2024
d52d8f7
Cygwin: console: Avoid slipping past disable_master_thread check.
tyan0 Feb 2, 2024
a4bd6e9
Cygwin: pipe: Give up to use query_hdl for non-cygwin apps.
tyan0 Mar 3, 2024
a4d92d6
Cygwin: pipe: Make sure to set read pipe non-blocking for cygwin apps.
tyan0 Mar 11, 2024
4eb0db9
Merge branch 'backport-fixes-3.4'
dscho Jul 9, 2024
2e2ef94
Merge branch 'better-onedrive-support'
dscho Jul 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ jobs:
shell: msys2 {0}
run: |
# XXX: cygwin still uses gcc v11 so we get new warnings with v13,
# resulting in errors. We can't selectively disable warnigns since our
# cross compiler is also too old and doesn't understand the new
# warning flags, so we need to disable all errors for now.
export CXXFLAGS="-Wno-error -Wno-narrowing"
# resulting in errors due to -Werror. Disable them for now.
export CXXFLAGS="-Wno-error=stringop-truncation -Wno-error=array-bounds -Wno-error=overloaded-virtual -Wno-narrowing -Wno-use-after-free"
(cd winsup && ./autogen.sh)
./configure --disable-dependency-tracking
make -j8
Expand Down
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
3 changes: 3 additions & 0 deletions winsup/cygwin/exceptions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1646,7 +1646,10 @@ _cygtls::call_signal_handler ()
context, unwind to the caller and in case we're called
from sigdelayed, fix the instruction pointer accordingly. */
context.uc_mcontext.ctxflags = CONTEXT_FULL;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
RtlCaptureContext ((PCONTEXT) &context.uc_mcontext);
#pragma GCC diagnostic pop
__unwind_single_frame ((PCONTEXT) &context.uc_mcontext);
if (stackptr > stack)
{
Expand Down
2 changes: 0 additions & 2 deletions winsup/cygwin/fhandler/console.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4344,8 +4344,6 @@ fhandler_console::need_console_handler ()
void
fhandler_console::set_disable_master_thread (bool x, fhandler_console *cons)
{
if (con.disable_master_thread == x)
return;
if (cons == NULL)
{
if (cygheap->ctty && cygheap->ctty->get_major () == DEV_CONS_MAJOR)
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
120 changes: 76 additions & 44 deletions winsup/cygwin/fhandler/pipe.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ details. */
#include "pinfo.h"
#include "shared_info.h"
#include "tls_pbuf.h"
#include "sigproc.h"
#include <assert.h>

/* This is only to be used for writing. When reading,
Expand Down Expand Up @@ -587,6 +588,17 @@ fhandler_pipe::fixup_after_fork (HANDLE parent)
ReleaseMutex (hdl_cnt_mtx);
}

void
fhandler_pipe::fixup_after_exec ()
{
/* Set read pipe itself always non-blocking for cygwin process.
Blocking/non-blocking is simulated in raw_read(). For write
pipe, follow is_nonblocking(). */
bool mode = get_device () == FH_PIPEW ? is_nonblocking () : true;
set_pipe_non_blocking (mode);
fhandler_base::fixup_after_exec ();
}

int
fhandler_pipe::dup (fhandler_base *child, int flags)
{
Expand Down Expand Up @@ -1207,53 +1219,24 @@ HANDLE
fhandler_pipe::get_query_hdl_per_process (WCHAR *name,
OBJECT_NAME_INFORMATION *ntfn)
{
NTSTATUS status;
ULONG len;
DWORD n_process = 256;
PSYSTEM_PROCESS_INFORMATION spi;
do
{ /* Enumerate processes */
DWORD nbytes = n_process * sizeof (SYSTEM_PROCESS_INFORMATION);
spi = (PSYSTEM_PROCESS_INFORMATION) HeapAlloc (GetProcessHeap (),
0, nbytes);
if (!spi)
return NULL;
status = NtQuerySystemInformation (SystemProcessInformation,
spi, nbytes, &len);
if (NT_SUCCESS (status))
break;
HeapFree (GetProcessHeap (), 0, spi);
n_process *= 2;
}
while (n_process < (1L<<20) && status == STATUS_INFO_LENGTH_MISMATCH);
if (!NT_SUCCESS (status))
return NULL;
winpids pids ((DWORD) 0);

/* In most cases, it is faster to check the processes in reverse order.
To do this, store PIDs into an array. */
DWORD *proc_pids = (DWORD *) HeapAlloc (GetProcessHeap (), 0,
n_process * sizeof (DWORD));
if (!proc_pids)
/* In most cases, it is faster to check the processes in reverse order. */
for (LONG i = (LONG) pids.npids - 1; i >= 0; i--)
{
HeapFree (GetProcessHeap (), 0, spi);
return NULL;
}
PSYSTEM_PROCESS_INFORMATION p = spi;
n_process = 0;
while (true)
{
proc_pids[n_process++] = (DWORD)(intptr_t) p->UniqueProcessId;
if (!p->NextEntryOffset)
break;
p = (PSYSTEM_PROCESS_INFORMATION) ((char *) p + p->NextEntryOffset);
}
HeapFree (GetProcessHeap (), 0, spi);
NTSTATUS status;
ULONG len;

/* Non-cygwin app may call ReadFile() for empty pipe, which makes
NtQueryObject() for ObjectNameInformation block. Therefore, do
not try to get query_hdl for non-cygwin apps. */
_pinfo *p = pids[i];
if (!p || ISSTATE (p, PID_NOTCYGWIN))
continue;

for (LONG i = (LONG) n_process - 1; i >= 0; i--)
{
HANDLE proc = OpenProcess (PROCESS_DUP_HANDLE
| PROCESS_QUERY_INFORMATION,
0, proc_pids[i]);
0, p->dwProcessId);
if (!proc)
continue;

Expand Down Expand Up @@ -1317,7 +1300,6 @@ fhandler_pipe::get_query_hdl_per_process (WCHAR *name,
query_hdl_proc = proc;
query_hdl_value = (HANDLE)(intptr_t) phi->Handles[j].HandleValue;
HeapFree (GetProcessHeap (), 0, phi);
HeapFree (GetProcessHeap (), 0, proc_pids);
return h;
}
close_handle:
Expand All @@ -1327,7 +1309,6 @@ fhandler_pipe::get_query_hdl_per_process (WCHAR *name,
close_proc:
CloseHandle (proc);
}
HeapFree (GetProcessHeap (), 0, proc_pids);
return NULL;
}

Expand Down Expand Up @@ -1401,3 +1382,54 @@ fhandler_pipe::get_query_hdl_per_system (WCHAR *name,
HeapFree (GetProcessHeap (), 0, shi);
return NULL;
}

void
fhandler_pipe::spawn_worker (int fileno_stdin, int fileno_stdout,
int fileno_stderr)
{
bool need_send_noncygchld_sig = false;

/* spawn_worker() is called from spawn.cc only when non-cygwin app
is started. Set pipe mode blocking for the non-cygwin process. */
int fd;
cygheap_fdenum cfd (false);
while ((fd = cfd.next ()) >= 0)
if (cfd->get_dev () == FH_PIPEW
&& (fd == fileno_stdout || fd == fileno_stderr))
{
fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
pipe->set_pipe_non_blocking (false);

/* Setup for query_ndl stuff. Read the comment below. */
if (pipe->request_close_query_hdl ())
need_send_noncygchld_sig = true;
}
else if (cfd->get_dev () == FH_PIPER && fd == fileno_stdin)
{
fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
pipe->set_pipe_non_blocking (false);
}

/* If multiple writers including non-cygwin app exist, the non-cygwin
app cannot detect pipe closure on the read side when the pipe is
created by system account or the pipe creator is running as service.
This is because query_hdl which is held in write side also is a read
end of the pipe, so the pipe is still alive for the non-cygwin app
even after the reader is closed.

To avoid this problem, let all processes in the same process
group close query_hdl using internal signal __SIGNONCYGCHLD when
non-cygwin app is started. */
if (need_send_noncygchld_sig)
{
tty_min dummy_tty;
dummy_tty.ntty = (fh_devices) myself->ctty;
dummy_tty.pgid = myself->pgid;
tty_min *t = cygwin_shared->tty.get_cttyp ();
if (!t) /* If tty is not allocated, use dummy_tty instead. */
t = &dummy_tty;
/* Emit __SIGNONCYGCHLD to let all processes in the
process group close query_hdl. */
t->kill_pgrp (__SIGNONCYGCHLD);
}
}
3 changes: 3 additions & 0 deletions winsup/cygwin/local_includes/fhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,7 @@ class fhandler_pipe: public fhandler_pipe_fifo
int open (int flags, mode_t mode = 0);
bool open_setup (int flags);
void fixup_after_fork (HANDLE);
void fixup_after_exec ();
int dup (fhandler_base *child, int);
void set_close_on_exec (bool val);
int close ();
Expand Down Expand Up @@ -1273,6 +1274,8 @@ class fhandler_pipe: public fhandler_pipe_fifo
}
return false;
}
static void spawn_worker (int fileno_stdin, int fileno_stdout,
int fileno_stderr);
};

#define CYGWIN_FIFO_PIPE_NAME_LEN 47
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
1 change: 0 additions & 1 deletion winsup/cygwin/msys2_path_conv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,6 @@ path_type find_path_start_and_type(const char** src, int recurse, const char* en
switch (*it) {
case '`':
case '\'':
case '"':
case '*':
case '?':
case '[':
Expand Down
Loading