diff --git a/Changelog.asciidoc b/Changelog.asciidoc index 68cad387..2d62ae86 100644 --- a/Changelog.asciidoc +++ b/Changelog.asciidoc @@ -1,6 +1,19 @@ = Changelog +v1.2POST1 (2017.2; issue #127):: + +Changes since v1.1: + +- WinFsp-FUSE now supports BSD flags (Windows file attributes) during `getattr` and `fgetattr`. It also adds the `chflags` operation. BSD flags support requires use of the `FSP_FUSE_CAP_STAT_EX` capability and the new `struct fuse_stat_ex` which includes an `st_flags` field. If the preprocessor macro `FSP_FUSE_USE_STAT_EX` is defined before inclusion of `` then `struct fuse_stat` will also be defined to include the `st_flags` field. +- WinFsp-FUSE also adds the following OSXFUSE operations: `setcrtime`, `setchgtime`. These can be used to set the creation (birth) time and change (ctime) time of a file. +- New `GetDirInfoByName` file system operation adds fast queries of directory info by file name rather than pattern [e.g. `FindFirstFileW(L"foobar", FindData)`]. Tests with fsbench showed that such queries are sped up by an order of magnitude when using `GetDirInfoByName` in MEMFS. Case-sensitive FUSE file systems get this optimization for free. The .NET layer also adds `GetDirInfoByName`. +- New `FspFileSystemOperationProcessId` API adds support for getting the originating process ID (PID) during `Create`, `Open` and `Rename` calls. FUSE file systems can now access `fuse_context::pid`. The .NET layer also adds `GetOperationProcessId`. +- New command line tool `fsptool` allows command line access to some WinFsp features. +- The WinFsp launcher now passes the name of the user who launched the file system as a special parameter %U. This is useful to file systems that use the launcher infrastructure, such as SSHFS-Win. [Please note that in earlier betas the user name was passed as parameter %3; the previous method was insecure and is no longer supported.] +- Important GitHub issues fixed: #96, #97, #103, #107, #127 + + v1.2 (2017.2):: Changes since v1.1: diff --git a/src/launcher/launcher.c b/src/launcher/launcher.c index c217eb4d..6c4abe52 100644 --- a/src/launcher/launcher.c +++ b/src/launcher/launcher.c @@ -23,12 +23,16 @@ #define PROGNAME "WinFsp.Launcher" BOOL CreateOverlappedPipe( - PHANDLE PReadPipe, PHANDLE PWritePipe, PSECURITY_ATTRIBUTES SecurityAttributes, DWORD Size, + PHANDLE PReadPipe, PHANDLE PWritePipe, + DWORD Size, + BOOL ReadInherit, BOOL WriteInherit, DWORD ReadMode, DWORD WriteMode) { RPC_STATUS RpcStatus; UUID Uuid; WCHAR PipeNameBuf[MAX_PATH]; + SECURITY_ATTRIBUTES ReadSecurityAttributes = { sizeof(SECURITY_ATTRIBUTES), 0, ReadInherit }; + SECURITY_ATTRIBUTES WriteSecurityAttributes = { sizeof(SECURITY_ATTRIBUTES), 0, WriteInherit }; HANDLE ReadPipe, WritePipe; DWORD LastError; @@ -48,13 +52,13 @@ BOOL CreateOverlappedPipe( ReadPipe = CreateNamedPipeW(PipeNameBuf, PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | ReadMode, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS, - 1, Size, Size, 120 * 1000, SecurityAttributes); + 1, Size, Size, 120 * 1000, &ReadSecurityAttributes); if (INVALID_HANDLE_VALUE == ReadPipe) return FALSE; WritePipe = CreateFileW(PipeNameBuf, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, - SecurityAttributes, OPEN_EXISTING, WriteMode, 0); + &WriteSecurityAttributes, OPEN_EXISTING, WriteMode, 0); if (INVALID_HANDLE_VALUE == WritePipe) { LastError = GetLastError(); @@ -552,7 +556,6 @@ NTSTATUS SvcInstanceCreateProcess(PWSTR UserName, STARTUPINFOEXW StartupInfoEx; HANDLE ChildHandles[3] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0/* DO NOT CLOSE!*/ }; HANDLE ParentHandles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; - SECURITY_ATTRIBUTES PipeAttributes = { sizeof(SECURITY_ATTRIBUTES), 0, TRUE }; PPROC_THREAD_ATTRIBUTE_LIST AttrList = 0; SIZE_T Size; NTSTATUS Result; @@ -570,16 +573,16 @@ NTSTATUS SvcInstanceCreateProcess(PWSTR UserName, */ /* create stdin read/write ends; make them inheritable */ - if (!CreateOverlappedPipe(&ChildHandles[0], &ParentHandles[0], &PipeAttributes, 0, - 0, 0)) + if (!CreateOverlappedPipe(&ChildHandles[0], &ParentHandles[0], + 0, TRUE, FALSE, 0, 0)) { Result = FspNtStatusFromWin32(GetLastError()); goto exit; } /* create stdout read/write ends; make them inheritable */ - if (!CreateOverlappedPipe(&ParentHandles[1], &ChildHandles[1], &PipeAttributes, 0, - FILE_FLAG_OVERLAPPED, 0)) + if (!CreateOverlappedPipe(&ParentHandles[1], &ChildHandles[1], + 0, FALSE, TRUE, FILE_FLAG_OVERLAPPED, 0)) { Result = FspNtStatusFromWin32(GetLastError()); goto exit; @@ -628,8 +631,28 @@ NTSTATUS SvcInstanceCreateProcess(PWSTR UserName, CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP | EXTENDED_STARTUPINFO_PRESENT, 0, 0, &StartupInfoEx.StartupInfo, ProcessInfo)) { - Result = FspNtStatusFromWin32(GetLastError()); - goto exit; + if (ERROR_NO_SYSTEM_RESOURCES != GetLastError()) + { + Result = FspNtStatusFromWin32(GetLastError()); + goto exit; + } + + /* + * On Win7 CreateProcessW with EXTENDED_STARTUPINFO_PRESENT + * may fail with ERROR_NO_SYSTEM_RESOURCES. + * + * In that case go ahead and retry with a CreateProcessW with + * bInheritHandles==TRUE, but without EXTENDED_STARTUPINFO_PRESENT. + * Not ideal, but... + */ + StartupInfoEx.StartupInfo.cb = sizeof StartupInfoEx.StartupInfo; + if (!CreateProcessW(Executable, CommandLine, 0, 0, TRUE, + CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP, 0, 0, + &StartupInfoEx.StartupInfo, ProcessInfo)) + { + Result = FspNtStatusFromWin32(GetLastError()); + goto exit; + } } } else @@ -1045,6 +1068,10 @@ exit: SvcInstanceRelease(SvcInstance); + if (STATUS_TIMEOUT == Result) + /* convert to an error! */ + Result = 0x80070000 | ERROR_TIMEOUT; + return Result; }