From a48668149b30f2cff96397f5cefc67e49e9ec17a Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Tue, 9 Jan 2018 11:38:27 -0800 Subject: [PATCH] inc: winfsp/launch.h --- build/VStudio/tools/launchctl.vcxproj | 1 - build/VStudio/tools/launchctl.vcxproj.filters | 3 - build/VStudio/tools/launcher.vcxproj | 1 - build/VStudio/tools/launcher.vcxproj.filters | 3 - build/VStudio/winfsp_dll.vcxproj | 1 + build/VStudio/winfsp_dll.vcxproj.filters | 3 + inc/winfsp/launch.h | 208 ++++++++++++++++++ inc/winfsp/winfsp.h | 127 ----------- src/dll/fs.c | 2 +- src/dll/launch.c | 25 +-- src/dll/library.h | 1 + src/dll/np.c | 12 +- src/launcher/launchctl.c | 35 +-- src/launcher/launcher.c | 46 ++-- src/launcher/launcher.h | 72 ------ 15 files changed, 275 insertions(+), 265 deletions(-) create mode 100644 inc/winfsp/launch.h delete mode 100644 src/launcher/launcher.h diff --git a/build/VStudio/tools/launchctl.vcxproj b/build/VStudio/tools/launchctl.vcxproj index e2001c4e..ed6b9d1a 100644 --- a/build/VStudio/tools/launchctl.vcxproj +++ b/build/VStudio/tools/launchctl.vcxproj @@ -185,7 +185,6 @@ - diff --git a/build/VStudio/tools/launchctl.vcxproj.filters b/build/VStudio/tools/launchctl.vcxproj.filters index 0a4c436d..09f921af 100644 --- a/build/VStudio/tools/launchctl.vcxproj.filters +++ b/build/VStudio/tools/launchctl.vcxproj.filters @@ -16,9 +16,6 @@ Include\shared - - Source - diff --git a/build/VStudio/tools/launcher.vcxproj b/build/VStudio/tools/launcher.vcxproj index e22a61c8..a3bfb809 100644 --- a/build/VStudio/tools/launcher.vcxproj +++ b/build/VStudio/tools/launcher.vcxproj @@ -197,7 +197,6 @@ - diff --git a/build/VStudio/tools/launcher.vcxproj.filters b/build/VStudio/tools/launcher.vcxproj.filters index acb13455..d2ad1d56 100644 --- a/build/VStudio/tools/launcher.vcxproj.filters +++ b/build/VStudio/tools/launcher.vcxproj.filters @@ -21,9 +21,6 @@ Include\shared - - Source - diff --git a/build/VStudio/winfsp_dll.vcxproj b/build/VStudio/winfsp_dll.vcxproj index 54553b37..7e3b7ac4 100644 --- a/build/VStudio/winfsp_dll.vcxproj +++ b/build/VStudio/winfsp_dll.vcxproj @@ -25,6 +25,7 @@ + diff --git a/build/VStudio/winfsp_dll.vcxproj.filters b/build/VStudio/winfsp_dll.vcxproj.filters index 00f55d7f..73bedbf3 100644 --- a/build/VStudio/winfsp_dll.vcxproj.filters +++ b/build/VStudio/winfsp_dll.vcxproj.filters @@ -53,6 +53,9 @@ Include\winfsp + + Include\winfsp + diff --git a/inc/winfsp/launch.h b/inc/winfsp/launch.h new file mode 100644 index 00000000..0317f7b7 --- /dev/null +++ b/inc/winfsp/launch.h @@ -0,0 +1,208 @@ +/** + * @file winfsp/launch.h + * WinFsp Launch API. + * + * In order to use the WinFsp API the user mode file system must include <winfsp/winfsp.h> + * and link with the winfsp_x64.dll (or winfsp_x86.dll) library. + * + * @copyright 2015-2018 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this file in + * accordance with the commercial license agreement provided with the + * software. + */ + +#ifndef WINFSP_LAUNCH_H_INCLUDED +#define WINFSP_LAUNCH_H_INCLUDED + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define FSP_LAUNCH_REGKEY "Software\\WinFsp\\Services" +#define FSP_LAUNCH_REGKEY_WOW64 KEY_WOW64_32KEY + +#define FSP_LAUNCH_PIPE_NAME "\\\\.\\pipe\\WinFsp.{14E7137D-22B4-437A-B0C1-D21D1BDF3767}" +#define FSP_LAUNCH_PIPE_BUFFER_SIZE 4096 +#define FSP_LAUNCH_PIPE_OWNER ((PSID)WinLocalSystemSid) + +/* + * The launcher named pipe SDDL gives full access to LocalSystem and Administrators and + * GENERIC_READ and FILE_WRITE_DATA access to Everyone. We are careful not to give the + * FILE_CREATE_PIPE_INSTANCE right to Everyone to disallow the creation of additional + * pipe instances. + */ +#define FSP_LAUNCH_PIPE_SDDL "O:SYG:SYD:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRDCCR;;;WD)" + + /* + * The default service instance SDDL gives full access to LocalSystem and Administrators. + * The only possible service instance rights are as follows: + * RP SERVICE_START + * WP SERVICE_STOP + * LC SERVICE_QUERY_STATUS + * + * To create a service that can be started, stopped or queried by Everyone, you can set + * the following SDDL: + * D:P(A;;RPWPLC;;;WD) + */ +#define FSP_LAUNCH_SERVICE_DEFAULT_SDDL "D:P(A;;RPWPLC;;;SY)(A;;RPWPLC;;;BA)" +#define FSP_LAUNCH_SERVICE_WORLD_SDDL "D:P(A;;RPWPLC;;;WD)" + +enum +{ + FspLaunchCmdStart = 'S', /* requires: SERVICE_START */ + FspLaunchCmdStartWithSecret = 'X', /* requires: SERVICE_START */ + FspLaunchCmdStop = 'T', /* requires: SERVICE_STOP */ + FspLaunchCmdGetInfo = 'I', /* requires: SERVICE_QUERY_STATUS */ + FspLaunchCmdGetNameList = 'L', /* requires: none*/ + FspLaunchCmdDefineDosDevice = 'D', /* internal: do not use! */ + FspLaunchCmdQuit = 'Q', /* DEBUG version only */ +}; + +enum +{ + FspLaunchCmdSuccess = '$', + FspLaunchCmdFailure = '!', +}; + +/** + * @group Launch Control + */ +/** + * Call launcher pipe. + * + * This function is used to send a command to the launcher and receive a response. + * + * @param Command + * Launcher command to send. For example, the 'L' launcher command instructs + * the launcher to list all running service instances. + * @param Argc + * Command argument count. May be 0. + * @param Argv + * Command argument array. May be NULL. + * @param Argl + * Command argument length array. May be NULL. If this is NULL all command arguments + * are assumed to be NULL-terminated strings. It is also possible for specific arguments + * to be NULL-terminated; in this case pass -1 in the corresponding Argl position. + * @param Buffer + * Buffer that receives the command response. May be NULL. + * @param PSize + * Pointer to a ULONG. On input it contains the size of the Buffer. On output it + * contains the number of bytes transferred. May be NULL. + * @param PLauncherError + * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. + * @return + * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher + * returns an error. Other status codes indicate a communication error. Launcher errors are + * reported through PLauncherError. + */ +FSP_API NTSTATUS FspLaunchCallLauncherPipe( + WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, + PWSTR Buffer, PULONG PSize, PULONG PLauncherError); +/** + * Start a service instance. + * + * @param ClassName + * Class name of the service instance to start. + * @param InstanceName + * Instance name of the service instance to start. + * @param Argc + * Service instance argument count. May be 0. + * @param Argv + * Service instance argument array. May be NULL. + * @param HasSecret + * Whether the last argument in Argv is assumed to be a secret (e.g. password) or not. + * Secrets are passed to service instances through standard input rather than the command + * line. + * @param PLauncherError + * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. + * @return + * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher + * returns an error. Other status codes indicate a communication error. Launcher errors are + * reported through PLauncherError. + */ +FSP_API NTSTATUS FspLaunchStart( + PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv0, + BOOLEAN HasSecret, + PULONG PLauncherError); +/** + * Stop a service instance. + * + * @param ClassName + * Class name of the service instance to stop. + * @param InstanceName + * Instance name of the service instance to stop. + * @param PLauncherError + * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. + * @return + * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher + * returns an error. Other status codes indicate a communication error. Launcher errors are + * reported through PLauncherError. + */ +FSP_API NTSTATUS FspLaunchStop( + PWSTR ClassName, PWSTR InstanceName, + PULONG PLauncherError); +/** + * Get information about a service instance. + * + * The information is a list of NULL-terminated strings: the class name of the service instance, + * the instance name of the service instance and the full command line used to start the service + * instance. + * + * @param ClassName + * Class name of the service instance to stop. + * @param InstanceName + * Instance name of the service instance to stop. + * @param Buffer + * Buffer that receives the command response. May be NULL. + * @param PSize + * Pointer to a ULONG. On input it contains the size of the Buffer. On output it + * contains the number of bytes transferred. May be NULL. + * @param PLauncherError + * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. + * @return + * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher + * returns an error. Other status codes indicate a communication error. Launcher errors are + * reported through PLauncherError. + */ +FSP_API NTSTATUS FspLaunchGetInfo( + PWSTR ClassName, PWSTR InstanceName, + PWSTR Buffer, PULONG PSize, + PULONG PLauncherError); +/** + * List service instances. + * + * The information is a list of pairs of NULL-terminated strings. Each pair contains the class + * name and instance name of a service instance. All currently running service instances are + * listed. + * + * @param Buffer + * Buffer that receives the command response. May be NULL. + * @param PSize + * Pointer to a ULONG. On input it contains the size of the Buffer. On output it + * contains the number of bytes transferred. May be NULL. + * @param PLauncherError + * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. + * @return + * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher + * returns an error. Other status codes indicate a communication error. Launcher errors are + * reported through PLauncherError. + */ +FSP_API NTSTATUS FspLaunchGetNameList( + PWSTR Buffer, PULONG PSize, + PULONG PLauncherError); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index d74b50aa..6892acc9 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -1703,133 +1703,6 @@ FSP_API NTSTATUS FspServiceContextCheck(HANDLE Token, PBOOLEAN PIsLocalSystem); FSP_API VOID FspServiceLog(ULONG Type, PWSTR Format, ...); FSP_API VOID FspServiceLogV(ULONG Type, PWSTR Format, va_list ap); -/** - * @group Launch Control - */ -/** - * Call launcher pipe. - * - * This function is used to send a command to the launcher and receive a response. - * - * @param Command - * Launcher command to send. For example, the 'L' launcher command instructs - * the launcher to list all running service instances. - * @param Argc - * Command argument count. May be 0. - * @param Argv - * Command argument array. May be NULL. - * @param Argl - * Command argument length array. May be NULL. If this is NULL all command arguments - * are assumed to be NULL-terminated strings. It is also possible for specific arguments - * to be NULL-terminated; in this case pass -1 in the corresponding Argl position. - * @param Buffer - * Buffer that receives the command response. May be NULL. - * @param PSize - * Pointer to a ULONG. On input it contains the size of the Buffer. On output it - * contains the number of bytes transferred. May be NULL. - * @param PLauncherError - * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. - * @return - * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher - * returns an error. Other status codes indicate a communication error. Launcher errors are - * reported through PLauncherError. - */ -FSP_API NTSTATUS FspLaunchCallLauncherPipe( - WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, - PWSTR Buffer, PULONG PSize, PULONG PLauncherError); -/** - * Start a service instance. - * - * @param ClassName - * Class name of the service instance to start. - * @param InstanceName - * Instance name of the service instance to start. - * @param Argc - * Service instance argument count. May be 0. - * @param Argv - * Service instance argument array. May be NULL. - * @param HasSecret - * Whether the last argument in Argv is assumed to be a secret (e.g. password) or not. - * Secrets are passed to service instances through standard input rather than the command - * line. - * @param PLauncherError - * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. - * @return - * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher - * returns an error. Other status codes indicate a communication error. Launcher errors are - * reported through PLauncherError. - */ -FSP_API NTSTATUS FspLaunchStart( - PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv0, - BOOLEAN HasSecret, - PULONG PLauncherError); -/** - * Stop a service instance. - * - * @param ClassName - * Class name of the service instance to stop. - * @param InstanceName - * Instance name of the service instance to stop. - * @param PLauncherError - * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. - * @return - * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher - * returns an error. Other status codes indicate a communication error. Launcher errors are - * reported through PLauncherError. - */ -FSP_API NTSTATUS FspLaunchStop( - PWSTR ClassName, PWSTR InstanceName, - PULONG PLauncherError); -/** - * Get information about a service instance. - * - * The information is a list of NULL-terminated strings: the class name of the service instance, - * the instance name of the service instance and the full command line used to start the service - * instance. - * - * @param ClassName - * Class name of the service instance to stop. - * @param InstanceName - * Instance name of the service instance to stop. - * @param Buffer - * Buffer that receives the command response. May be NULL. - * @param PSize - * Pointer to a ULONG. On input it contains the size of the Buffer. On output it - * contains the number of bytes transferred. May be NULL. - * @param PLauncherError - * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. - * @return - * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher - * returns an error. Other status codes indicate a communication error. Launcher errors are - * reported through PLauncherError. - */ -FSP_API NTSTATUS FspLaunchGetInfo( - PWSTR ClassName, PWSTR InstanceName, - PWSTR Buffer, PULONG PSize, - PULONG PLauncherError); -/** - * List service instances. - * - * The information is a list of pairs of NULL-terminated strings. Each pair contains the class - * name and instance name of a service instance. All currently running service instances are - * listed. - * - * @param Buffer - * Buffer that receives the command response. May be NULL. - * @param PSize - * Pointer to a ULONG. On input it contains the size of the Buffer. On output it - * contains the number of bytes transferred. May be NULL. - * @param PLauncherError - * Receives the launcher error if any. This is always a Win32 error code. May not be NULL. - * @return - * STATUS_SUCCESS if the command is sent successfully to the launcher, even if the launcher - * returns an error. Other status codes indicate a communication error. Launcher errors are - * reported through PLauncherError. - */ -FSP_API NTSTATUS FspLaunchGetNameList( - PWSTR Buffer, PULONG PSize, - PULONG PLauncherError); - /* * Utility */ diff --git a/src/dll/fs.c b/src/dll/fs.c index 66a277b9..d102a32a 100644 --- a/src/dll/fs.c +++ b/src/dll/fs.c @@ -207,7 +207,7 @@ static NTSTATUS FspFileSystemLauncherDefineDosDevice( Argv[0] = Argv0; Argv[1] = VolumeName; - Result = FspLaunchCallLauncherPipe('D', 2, Argv, 0, 0, 0, &ErrorCode); + Result = FspLaunchCallLauncherPipe(FspLaunchCmdDefineDosDevice, 2, Argv, 0, 0, 0, &ErrorCode); return !NT_SUCCESS(Result) ? Result : FspNtStatusFromWin32(ErrorCode); } diff --git a/src/dll/launch.c b/src/dll/launch.c index 03042f4c..03308796 100644 --- a/src/dll/launch.c +++ b/src/dll/launch.c @@ -16,7 +16,6 @@ */ #include -#include FSP_API NTSTATUS FspLaunchCallLauncherPipe( WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, @@ -31,7 +30,7 @@ FSP_API NTSTATUS FspLaunchCallLauncherPipe( *PSize = 0; *PLauncherError = 0; - PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE); + PipeBuf = MemAlloc(FSP_LAUNCH_PIPE_BUFFER_SIZE); if (0 == PipeBuf) { Result = STATUS_INSUFFICIENT_RESOURCES; @@ -44,7 +43,7 @@ FSP_API NTSTATUS FspLaunchCallLauncherPipe( if (0 != Argv[I]) { Length = 0 == Argl || -1 == Argl[I] ? lstrlenW(Argv[I]) : Argl[I]; - if (LAUNCHER_PIPE_BUFFER_SIZE < ((ULONG)(P - PipeBuf) + Length + 1) * sizeof(WCHAR)) + if (FSP_LAUNCH_PIPE_BUFFER_SIZE < ((ULONG)(P - PipeBuf) + Length + 1) * sizeof(WCHAR)) { Result = STATUS_INVALID_PARAMETER; goto exit; @@ -52,9 +51,9 @@ FSP_API NTSTATUS FspLaunchCallLauncherPipe( memcpy(P, Argv[I], Length * sizeof(WCHAR)); P += Length; *P++ = L'\0'; } - Result = FspCallNamedPipeSecurely(L"" LAUNCHER_PIPE_NAME, - PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE, - &BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, LAUNCHER_PIPE_OWNER); + Result = FspCallNamedPipeSecurely(L"" FSP_LAUNCH_PIPE_NAME, + PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), PipeBuf, FSP_LAUNCH_PIPE_BUFFER_SIZE, + &BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, FSP_LAUNCH_PIPE_OWNER); if (!NT_SUCCESS(Result)) goto exit; @@ -62,18 +61,18 @@ FSP_API NTSTATUS FspLaunchCallLauncherPipe( ErrorCode = ERROR_BROKEN_PIPE; /* protocol error! */ if (sizeof(WCHAR) <= BytesTransferred) { - if (LauncherSuccess == PipeBuf[0]) + if (FspLaunchCmdSuccess == PipeBuf[0]) { ErrorCode = 0; if (0 != PSize) { BytesTransferred -= sizeof(WCHAR); - memcpy(Buffer, PipeBuf, *PSize < BytesTransferred ? *PSize : BytesTransferred); + memcpy(Buffer, PipeBuf + 1, *PSize < BytesTransferred ? *PSize : BytesTransferred); *PSize = BytesTransferred; } } - else if (LauncherFailure == PipeBuf[0]) + else if (FspLaunchCmdFailure == PipeBuf[0]) { ErrorCode = 0; @@ -112,7 +111,7 @@ FSP_API NTSTATUS FspLaunchStart( memcpy(Argv + 2, Argv, Argc * sizeof(PWSTR)); return FspLaunchCallLauncherPipe( - HasSecret ? LauncherSvcInstanceStartWithSecret : LauncherSvcInstanceStart, + HasSecret ? FspLaunchCmdStartWithSecret : FspLaunchCmdStart, Argc + 2, Argv, 0, 0, 0, PLauncherError); } @@ -125,7 +124,7 @@ FSP_API NTSTATUS FspLaunchStop( Argv[0] = ClassName; Argv[1] = InstanceName; - return FspLaunchCallLauncherPipe(LauncherSvcInstanceStop, + return FspLaunchCallLauncherPipe(FspLaunchCmdStop, 2, Argv, 0, 0, 0, PLauncherError); } @@ -139,7 +138,7 @@ FSP_API NTSTATUS FspLaunchGetInfo( Argv[0] = ClassName; Argv[1] = InstanceName; - return FspLaunchCallLauncherPipe(LauncherSvcInstanceInfo, + return FspLaunchCallLauncherPipe(FspLaunchCmdGetInfo, 2, Argv, 0, Buffer, PSize, PLauncherError); } @@ -147,6 +146,6 @@ FSP_API NTSTATUS FspLaunchGetNameList( PWSTR Buffer, PULONG PSize, PULONG PLauncherError) { - return FspLaunchCallLauncherPipe(LauncherSvcInstanceList, + return FspLaunchCallLauncherPipe(FspLaunchCmdGetNameList, 0, 0, 0, Buffer, PSize, PLauncherError); } diff --git a/src/dll/library.h b/src/dll/library.h index e0739e41..08eb56f3 100644 --- a/src/dll/library.h +++ b/src/dll/library.h @@ -20,6 +20,7 @@ #define WINFSP_DLL_INTERNAL #include +#include #include #include diff --git a/src/dll/np.c b/src/dll/np.c index bac9047b..adf4c7f9 100644 --- a/src/dll/np.c +++ b/src/dll/np.c @@ -16,7 +16,6 @@ */ #include -#include #include #include @@ -268,8 +267,8 @@ static DWORD FspNpGetCredentialsKind(PWSTR RemoteName, PDWORD PCredentialsKind) memcpy(ClassNameBuf, ClassName, ClassNameLen * sizeof(WCHAR)); ClassNameBuf[ClassNameLen] = '\0'; - NpResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"" LAUNCHER_REGKEY, - 0, LAUNCHER_REGKEY_WOW64 | KEY_READ, &RegKey); + NpResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"" FSP_LAUNCH_REGKEY, + 0, FSP_LAUNCH_REGKEY_WOW64 | KEY_READ, &RegKey); if (ERROR_SUCCESS != NpResult) goto exit; @@ -557,8 +556,7 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword, } NpResult = FspNpCallLauncherPipe( - FSP_NP_CREDENTIALS_NONE != CredentialsKind ? - LauncherSvcInstanceStartWithSecret : LauncherSvcInstanceStart, + FSP_NP_CREDENTIALS_NONE != CredentialsKind ? FspLaunchCmdStartWithSecret : FspLaunchCmdStart, Argc, Argv, Argl, 0, 0); switch (NpResult) { @@ -610,7 +608,7 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword, Argv[Argc] = InstanceName; Argl[Argc] = InstanceNameLen; Argc++; if (WN_SUCCESS != FspNpCallLauncherPipe( - LauncherSvcInstanceInfo, + FspLaunchCmdGetInfo, Argc, Argv, Argl, 0, 0)) { /* looks like the file system is gone! */ @@ -772,7 +770,7 @@ DWORD APIENTRY NPCancelConnection(LPWSTR lpName, BOOL fForce) Argv[Argc] = InstanceName; Argl[Argc] = InstanceNameLen; Argc++; NpResult = FspNpCallLauncherPipe( - LauncherSvcInstanceStop, + FspLaunchCmdStop, Argc, Argv, Argl, 0, 0); switch (NpResult) { diff --git a/src/launcher/launchctl.c b/src/launcher/launchctl.c index 48cf9d14..7ff74cc8 100644 --- a/src/launcher/launchctl.c +++ b/src/launcher/launchctl.c @@ -15,7 +15,8 @@ * software. */ -#include +#include +#include #define PROGNAME "launchctl" @@ -67,15 +68,15 @@ static int call_pipe_and_report(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize) NTSTATUS Result; DWORD LastError, BytesTransferred; - Result = FspCallNamedPipeSecurely(L"" LAUNCHER_PIPE_NAME, PipeBuf, SendSize, PipeBuf, RecvSize, - &BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, LAUNCHER_PIPE_OWNER); + Result = FspCallNamedPipeSecurely(L"" FSP_LAUNCH_PIPE_NAME, PipeBuf, SendSize, PipeBuf, RecvSize, + &BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, FSP_LAUNCH_PIPE_OWNER); LastError = FspWin32FromNtStatus(Result); if (0 != LastError) warn("KO CallNamedPipe = %ld", LastError); else if (sizeof(WCHAR) > BytesTransferred) warn("KO launcher: empty buffer"); - else if (LauncherSuccess == PipeBuf[0]) + else if (FspLaunchCmdSuccess == PipeBuf[0]) { if (sizeof(WCHAR) == BytesTransferred) info("OK"); @@ -100,7 +101,7 @@ static int call_pipe_and_report(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize) info("OK\n%S", PipeBuf + 1); } } - else if (LauncherFailure == PipeBuf[0]) + else if (FspLaunchCmdFailure == PipeBuf[0]) { if (BytesTransferred < RecvSize) PipeBuf[BytesTransferred / sizeof(WCHAR)] = L'\0'; @@ -132,7 +133,7 @@ int start(PWSTR PipeBuf, ULONG PipeBufSize, return ERROR_INVALID_PARAMETER; P = PipeBuf; - *P++ = HasSecret ? LauncherSvcInstanceStartWithSecret : LauncherSvcInstanceStart; + *P++ = HasSecret ? FspLaunchCmdStartWithSecret : FspLaunchCmdStart; memcpy(P, ClassName, ClassNameSize * sizeof(WCHAR)); P += ClassNameSize; memcpy(P, InstanceName, InstanceNameSize * sizeof(WCHAR)); P += InstanceNameSize; for (DWORD Argi = 0; Argc > Argi; Argi++) @@ -157,7 +158,7 @@ int stop(PWSTR PipeBuf, ULONG PipeBufSize, return ERROR_INVALID_PARAMETER; P = PipeBuf; - *P++ = LauncherSvcInstanceStop; + *P++ = FspLaunchCmdStop; memcpy(P, ClassName, ClassNameSize * sizeof(WCHAR)); P += ClassNameSize; memcpy(P, InstanceName, InstanceNameSize * sizeof(WCHAR)); P += InstanceNameSize; @@ -177,7 +178,7 @@ int getinfo(PWSTR PipeBuf, ULONG PipeBufSize, return ERROR_INVALID_PARAMETER; P = PipeBuf; - *P++ = LauncherSvcInstanceInfo; + *P++ = FspLaunchCmdGetInfo; memcpy(P, ClassName, ClassNameSize * sizeof(WCHAR)); P += ClassNameSize; memcpy(P, InstanceName, InstanceNameSize * sizeof(WCHAR)); P += InstanceNameSize; @@ -192,7 +193,7 @@ int list(PWSTR PipeBuf, ULONG PipeBufSize) return ERROR_INVALID_PARAMETER; P = PipeBuf; - *P++ = LauncherSvcInstanceList; + *P++ = FspLaunchCmdGetNameList; return call_pipe_and_report(PipeBuf, (ULONG)((P - PipeBuf) * sizeof(WCHAR)), PipeBufSize); } @@ -207,7 +208,7 @@ int quit(PWSTR PipeBuf, ULONG PipeBufSize) return ERROR_INVALID_PARAMETER; P = PipeBuf; - *P++ = LauncherQuit; + *P++ = FspLaunchCmdQuit; return call_pipe_and_report(PipeBuf, (ULONG)((P - PipeBuf) * sizeof(WCHAR)), PipeBufSize); } @@ -217,7 +218,7 @@ int wmain(int argc, wchar_t **argv) PWSTR PipeBuf = 0; /* allocate our PipeBuf early on; freed on process exit by the system */ - PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE); + PipeBuf = MemAlloc(FSP_LAUNCH_PIPE_BUFFER_SIZE); if (0 == PipeBuf) return ERROR_NO_SYSTEM_RESOURCES; @@ -232,7 +233,7 @@ int wmain(int argc, wchar_t **argv) if (3 > argc || argc > 12) usage(); - return start(PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE, argv[1], argv[2], argc - 3, argv + 3, + return start(PipeBuf, FSP_LAUNCH_PIPE_BUFFER_SIZE, argv[1], argv[2], argc - 3, argv + 3, FALSE); } else @@ -241,7 +242,7 @@ int wmain(int argc, wchar_t **argv) if (4 > argc || argc > 13) usage(); - return start(PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE, argv[1], argv[2], argc - 3, argv + 3, + return start(PipeBuf, FSP_LAUNCH_PIPE_BUFFER_SIZE, argv[1], argv[2], argc - 3, argv + 3, TRUE); } else @@ -250,7 +251,7 @@ int wmain(int argc, wchar_t **argv) if (3 != argc) usage(); - return stop(PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE, argv[1], argv[2]); + return stop(PipeBuf, FSP_LAUNCH_PIPE_BUFFER_SIZE, argv[1], argv[2]); } else if (0 == invariant_wcscmp(L"info", argv[0])) @@ -258,7 +259,7 @@ int wmain(int argc, wchar_t **argv) if (3 != argc) usage(); - return getinfo(PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE, argv[1], argv[2]); + return getinfo(PipeBuf, FSP_LAUNCH_PIPE_BUFFER_SIZE, argv[1], argv[2]); } else if (0 == invariant_wcscmp(L"list", argv[0])) @@ -266,7 +267,7 @@ int wmain(int argc, wchar_t **argv) if (1 != argc) usage(); - return list(PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE); + return list(PipeBuf, FSP_LAUNCH_PIPE_BUFFER_SIZE); } else if (0 == invariant_wcscmp(L"quit", argv[0])) @@ -275,7 +276,7 @@ int wmain(int argc, wchar_t **argv) usage(); /* works only against DEBUG version of launcher */ - return quit(PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE); + return quit(PipeBuf, FSP_LAUNCH_PIPE_BUFFER_SIZE); } else usage(); diff --git a/src/launcher/launcher.c b/src/launcher/launcher.c index 40fac631..f9168c08 100644 --- a/src/launcher/launcher.c +++ b/src/launcher/launcher.c @@ -15,7 +15,8 @@ * software. */ -#include +#include +#include #include #include #include @@ -410,6 +411,11 @@ static VOID CALLBACK KillProcessWait(PVOID Context, BOOLEAN Timeout) MemFree(KillProcessData); } +#define LAUNCHER_PIPE_DEFAULT_TIMEOUT (2 * 15000 + 1000) +#define LAUNCHER_START_WITH_SECRET_TIMEOUT 15000 +#define LAUNCHER_STOP_TIMEOUT 5500 +#define LAUNCHER_KILL_TIMEOUT 5000 + typedef struct { LONG RefCount; @@ -858,8 +864,8 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken, goto exit; } - RegResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"" LAUNCHER_REGKEY, - 0, LAUNCHER_REGKEY_WOW64 | KEY_READ, &RegKey); + RegResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"" FSP_LAUNCH_REGKEY, + 0, FSP_LAUNCH_REGKEY_WOW64 | KEY_READ, &RegKey); if (ERROR_SUCCESS != RegResult) { Result = FspNtStatusFromWin32(RegResult); @@ -950,7 +956,7 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken, RegKey = 0; if (L'\0' == Security[0]) - lstrcpyW(Security, L"" SVC_INSTANCE_DEFAULT_SDDL); + lstrcpyW(Security, L"" FSP_LAUNCH_SERVICE_DEFAULT_SDDL); if (L'D' == Security[0] && L':' == Security[1]) Security = SecurityBuf; @@ -1412,7 +1418,7 @@ static NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv) SecurityAttributes.nLength = sizeof SecurityAttributes; SecurityAttributes.bInheritHandle = FALSE; - if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(L"" LAUNCHER_PIPE_SDDL, SDDL_REVISION_1, + if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(L"" FSP_LAUNCH_PIPE_SDDL, SDDL_REVISION_1, &SecurityAttributes.lpSecurityDescriptor, 0)) goto fail; @@ -1449,11 +1455,11 @@ static NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv) if (0 == SvcOverlapped.hEvent) goto fail; - SvcPipe = CreateNamedPipeW(L"" LAUNCHER_PIPE_NAME, + SvcPipe = CreateNamedPipeW(L"" FSP_LAUNCH_PIPE_NAME, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS, - 1, LAUNCHER_PIPE_BUFFER_SIZE, LAUNCHER_PIPE_BUFFER_SIZE, LAUNCHER_PIPE_DEFAULT_TIMEOUT, + 1, FSP_LAUNCH_PIPE_BUFFER_SIZE, FSP_LAUNCH_PIPE_BUFFER_SIZE, LAUNCHER_PIPE_DEFAULT_TIMEOUT, &SecurityAttributes); if (INVALID_HANDLE_VALUE == SvcPipe) goto fail; @@ -1581,7 +1587,7 @@ static DWORD WINAPI SvcPipeServer(PVOID Context) HANDLE ClientToken; DWORD LastError, BytesTransferred; - PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE); + PipeBuf = MemAlloc(FSP_LAUNCH_PIPE_BUFFER_SIZE); if (0 == PipeBuf) { FspServiceSetExitCode(Service, ERROR_NO_SYSTEM_RESOURCES); @@ -1604,7 +1610,7 @@ static DWORD WINAPI SvcPipeServer(PVOID Context) } LastError = SvcPipeWaitResult( - ReadFile(SvcPipe, PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE, &BytesTransferred, &SvcOverlapped), + ReadFile(SvcPipe, PipeBuf, FSP_LAUNCH_PIPE_BUFFER_SIZE, &BytesTransferred, &SvcOverlapped), SvcEvent, SvcPipe, &SvcOverlapped, &BytesTransferred); if (-1 == LastError) break; @@ -1694,11 +1700,11 @@ static inline VOID SvcPipeTransactResult(NTSTATUS Result, PWSTR PipeBuf, PULONG { if (NT_SUCCESS(Result)) { - *PipeBuf = LauncherSuccess; + *PipeBuf = FspLaunchCmdSuccess; *PSize += sizeof(WCHAR); } else - *PSize = (wsprintfW(PipeBuf, L"%c%ld", LauncherFailure, FspWin32FromNtStatus(Result)) + 1) * + *PSize = (wsprintfW(PipeBuf, L"%c%ld", FspLaunchCmdFailure, FspWin32FromNtStatus(Result)) + 1) * sizeof(WCHAR); } @@ -1721,10 +1727,10 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize) switch (*P++) { - case LauncherSvcInstanceStartWithSecret: + case FspLaunchCmdStartWithSecret: HasSecret = TRUE; /* fall through! */ - case LauncherSvcInstanceStart: + case FspLaunchCmdStart: ClassName = SvcPipeTransactGetPart(&P, PipeBufEnd); InstanceName = SvcPipeTransactGetPart(&P, PipeBufEnd); for (Argc = 0; sizeof Argv / sizeof Argv[0] > Argc; Argc++) @@ -1739,7 +1745,7 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize) SvcPipeTransactResult(Result, PipeBuf, PSize); break; - case LauncherSvcInstanceStop: + case FspLaunchCmdStop: ClassName = SvcPipeTransactGetPart(&P, PipeBufEnd); InstanceName = SvcPipeTransactGetPart(&P, PipeBufEnd); @@ -1750,28 +1756,28 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize) SvcPipeTransactResult(Result, PipeBuf, PSize); break; - case LauncherSvcInstanceInfo: + case FspLaunchCmdGetInfo: ClassName = SvcPipeTransactGetPart(&P, PipeBufEnd); InstanceName = SvcPipeTransactGetPart(&P, PipeBufEnd); Result = STATUS_INVALID_PARAMETER; if (0 != ClassName && 0 != InstanceName) { - *PSize = LAUNCHER_PIPE_BUFFER_SIZE - 1; + *PSize = FSP_LAUNCH_PIPE_BUFFER_SIZE - 1; Result = SvcInstanceGetInfo(ClientToken, ClassName, InstanceName, PipeBuf + 1, PSize); } SvcPipeTransactResult(Result, PipeBuf, PSize); break; - case LauncherSvcInstanceList: - *PSize = LAUNCHER_PIPE_BUFFER_SIZE - 1; + case FspLaunchCmdGetNameList: + *PSize = FSP_LAUNCH_PIPE_BUFFER_SIZE - 1; Result = SvcInstanceGetNameList(ClientToken, PipeBuf + 1, PSize); SvcPipeTransactResult(Result, PipeBuf, PSize); break; - case LauncherDefineDosDevice: + case FspLaunchCmdDefineDosDevice: DeviceName = SvcPipeTransactGetPart(&P, PipeBufEnd); TargetPath = SvcPipeTransactGetPart(&P, PipeBufEnd); @@ -1783,7 +1789,7 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize) break; #if !defined(NDEBUG) - case LauncherQuit: + case FspLaunchCmdQuit: SetEvent(SvcEvent); SvcPipeTransactResult(STATUS_SUCCESS, PipeBuf, PSize); diff --git a/src/launcher/launcher.h b/src/launcher/launcher.h deleted file mode 100644 index 9e77b228..00000000 --- a/src/launcher/launcher.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @file launcher/launcher.h - * - * @copyright 2015-2018 Bill Zissimopoulos - */ -/* - * This file is part of WinFsp. - * - * You can redistribute it and/or modify it under the terms of the GNU - * General Public License version 3 as published by the Free Software - * Foundation. - * - * Licensees holding a valid commercial license may use this file in - * accordance with the commercial license agreement provided with the - * software. - */ - -#ifndef WINFSP_LAUNCHER_LAUNCHER_H_INCLUDED -#define WINFSP_LAUNCHER_LAUNCHER_H_INCLUDED - -#include -#include - -#define LAUNCHER_REGKEY "Software\\WinFsp\\Services" -#define LAUNCHER_REGKEY_WOW64 KEY_WOW64_32KEY - -#define LAUNCHER_STOP_TIMEOUT 5500 -#define LAUNCHER_KILL_TIMEOUT 5000 - -#define LAUNCHER_PIPE_NAME "\\\\.\\pipe\\WinFsp.{14E7137D-22B4-437A-B0C1-D21D1BDF3767}" -#define LAUNCHER_PIPE_BUFFER_SIZE 4096 -#define LAUNCHER_PIPE_DEFAULT_TIMEOUT (2 * 15000 + 1000) - -#define LAUNCHER_START_WITH_SECRET_TIMEOUT 15000 - -/* - * The launcher named pipe SDDL gives full access to LocalSystem and Administrators and - * GENERIC_READ and FILE_WRITE_DATA access to Everyone. We are careful not to give the - * FILE_CREATE_PIPE_INSTANCE right to Everyone to disallow the creation of additional - * pipe instances. - */ -#define LAUNCHER_PIPE_SDDL "O:SYG:SYD:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRDCCR;;;WD)" -#define LAUNCHER_PIPE_OWNER ((PSID)WinLocalSystemSid) - - /* - * The default service instance SDDL gives full access to LocalSystem and Administrators. - * The only possible service instance rights are as follows: - * RP SERVICE_START - * WP SERVICE_STOP - * LC SERVICE_QUERY_STATUS - * - * To create a service that can be started, stopped or queried by Everyone, you can set - * the following SDDL: - * D:P(A;;RPWPLC;;;WD) - */ -#define SVC_INSTANCE_DEFAULT_SDDL "D:P(A;;RPWPLC;;;SY)(A;;RPWPLC;;;BA)" - -enum -{ - LauncherSvcInstanceStart = 'S', /* requires: SERVICE_START */ - LauncherSvcInstanceStartWithSecret = 'X', /* requires: SERVICE_START */ - LauncherSvcInstanceStop = 'T', /* requires: SERVICE_STOP */ - LauncherSvcInstanceInfo = 'I', /* requires: SERVICE_QUERY_STATUS */ - LauncherSvcInstanceList = 'L', /* requires: none*/ - LauncherDefineDosDevice = 'D', - LauncherQuit = 'Q', /* DEBUG version only */ - - LauncherSuccess = '$', - LauncherFailure = '!', -}; - -#endif