dll: fuse: only use the environment's malloc prior to fsp_fuse_loop

- this allows an environment like Cygwin to safely call fork prior to fuse_loop/fuse_loop_mt
This commit is contained in:
Bill Zissimopoulos 2016-06-15 23:12:08 -07:00
parent b8ec5ba019
commit b695ef8ad8
7 changed files with 92 additions and 100 deletions

View File

@ -229,7 +229,6 @@ struct fsp_fuse_env
}; };
FSP_FUSE_API void fsp_fuse_signal_handler(int sig); FSP_FUSE_API void fsp_fuse_signal_handler(int sig);
FSP_FUSE_API void fsp_fuse_set_signal_arg(void *se);
#if defined(_WIN64) || defined(_WIN32) #if defined(_WIN64) || defined(_WIN32)
@ -304,13 +303,8 @@ static inline int fsp_fuse_set_signal_handlers(void *se)
if (0 != pthread_sigmask(SIG_BLOCK, &sigmask, 0)) if (0 != pthread_sigmask(SIG_BLOCK, &sigmask, 0))
return -1; return -1;
fsp_fuse_set_signal_arg(se);
if (0 != pthread_create(&sigthr, 0, fsp_fuse_signal_thread, &sigmask)) if (0 != pthread_create(&sigthr, 0, fsp_fuse_signal_thread, &sigmask))
{
fsp_fuse_set_signal_arg(0);
return -1; return -1;
}
} }
} }
else else
@ -321,8 +315,6 @@ static inline int fsp_fuse_set_signal_handlers(void *se)
pthread_join(sigthr, 0); pthread_join(sigthr, 0);
sigthr = 0; sigthr = 0;
fsp_fuse_set_signal_arg(0);
if (0 != pthread_sigmask(SIG_UNBLOCK, &sigmask, 0)) if (0 != pthread_sigmask(SIG_UNBLOCK, &sigmask, 0))
return -1; return -1;
sigemptyset(&sigmask); sigemptyset(&sigmask);

View File

@ -931,10 +931,19 @@ typedef struct _FSP_SERVICE
* @return * @return
* Service process exit code. * Service process exit code.
*/ */
FSP_API ULONG FspServiceRun(PWSTR ServiceName, FSP_API ULONG FspServiceRunEx(PWSTR ServiceName,
FSP_SERVICE_START *OnStart, FSP_SERVICE_START *OnStart,
FSP_SERVICE_STOP *OnStop, FSP_SERVICE_STOP *OnStop,
FSP_SERVICE_CONTROL *OnControl); FSP_SERVICE_CONTROL *OnControl,
PVOID UserContext);
static inline
ULONG FspServiceRun(PWSTR ServiceName,
FSP_SERVICE_START *OnStart,
FSP_SERVICE_STOP *OnStop,
FSP_SERVICE_CONTROL *OnControl)
{
return FspServiceRunEx(ServiceName, OnStart, OnStop, OnControl, 0);
}
/** /**
* Create a service object. * Create a service object.
* *

View File

@ -103,6 +103,32 @@ static struct fuse_opt fsp_fuse_core_opts[] =
static DWORD fsp_fuse_tlskey = TLS_OUT_OF_INDEXES; static DWORD fsp_fuse_tlskey = TLS_OUT_OF_INDEXES;
static INIT_ONCE fsp_fuse_initonce_v = INIT_ONCE_STATIC_INIT; static INIT_ONCE fsp_fuse_initonce_v = INIT_ONCE_STATIC_INIT;
struct fsp_fuse_obj_hdr
{
void (*dtor)(void *);
__declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 ObjectBuf[];
};
static inline void *fsp_fuse_obj_alloc(struct fsp_fuse_env *env, size_t size)
{
struct fsp_fuse_obj_hdr *hdr;
hdr = env->memalloc(sizeof(struct fsp_fuse_obj_hdr) + size);
if (0 == hdr)
return 0;
hdr->dtor = env->memfree;
memset(hdr->ObjectBuf, 0, size);
return hdr->ObjectBuf;
}
static inline void fsp_fuse_obj_free(void *obj)
{
struct fsp_fuse_obj_hdr *hdr = (PVOID)((PUINT8)obj - sizeof(struct fsp_fuse_obj_hdr));
hdr->dtor(hdr);
}
VOID fsp_fuse_initialize(BOOLEAN Dynamic) VOID fsp_fuse_initialize(BOOLEAN Dynamic)
{ {
} }
@ -139,10 +165,7 @@ VOID fsp_fuse_finalize_thread(VOID)
context = TlsGetValue(fsp_fuse_tlskey); context = TlsGetValue(fsp_fuse_tlskey);
if (0 != context) if (0 != context)
{ {
struct fsp_fuse_context_header *contexthdr = fsp_fuse_obj_free(FSP_FUSE_HDR_FROM_CONTEXT(context));
(PVOID)((PUINT8)context - sizeof *contexthdr);
MemFree(contexthdr);
TlsSetValue(fsp_fuse_tlskey, 0); TlsSetValue(fsp_fuse_tlskey, 0);
} }
} }
@ -178,7 +201,7 @@ FSP_FUSE_API struct fuse_chan *fsp_fuse_mount(struct fsp_fuse_env *env,
if (0 == Size) if (0 == Size)
goto fail; goto fail;
ch = MemAlloc(sizeof *ch + Size * sizeof(WCHAR)); ch = fsp_fuse_obj_alloc(env, sizeof *ch + Size * sizeof(WCHAR));
if (0 == ch) if (0 == ch)
goto fail; goto fail;
@ -190,7 +213,7 @@ FSP_FUSE_API struct fuse_chan *fsp_fuse_mount(struct fsp_fuse_env *env,
return ch; return ch;
fail: fail:
MemFree(ch); fsp_fuse_obj_free(ch);
return 0; return 0;
} }
@ -198,7 +221,7 @@ fail:
FSP_FUSE_API void fsp_fuse_unmount(struct fsp_fuse_env *env, FSP_FUSE_API void fsp_fuse_unmount(struct fsp_fuse_env *env,
const char *mountpoint, struct fuse_chan *ch) const char *mountpoint, struct fuse_chan *ch)
{ {
MemFree(ch); fsp_fuse_obj_free(ch);
} }
FSP_FUSE_API int fsp_fuse_is_lib_option(struct fsp_fuse_env *env, FSP_FUSE_API int fsp_fuse_is_lib_option(struct fsp_fuse_env *env,
@ -246,7 +269,9 @@ static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
struct fuse_conn_info conn; struct fuse_conn_info conn;
NTSTATUS Result; NTSTATUS Result;
context = fsp_fuse_get_context(0); f->Service = Service;
context = fsp_fuse_get_context(f->env);
if (0 == context) if (0 == context)
{ {
Result = STATUS_INSUFFICIENT_RESOURCES; Result = STATUS_INSUFFICIENT_RESOURCES;
@ -410,6 +435,8 @@ static void fsp_fuse_cleanup(struct fuse *f)
f->ops.destroy(f->data); f->ops.destroy(f->data);
f->fsinit = FALSE; f->fsinit = FALSE;
} }
f->Service = 0;
} }
static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key, static int fsp_fuse_core_opt_proc(void *opt_data0, const char *arg, int key,
@ -484,10 +511,9 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
opt_data.VolumeParams.NamedStreams = !!opt_data.NamedStreams; opt_data.VolumeParams.NamedStreams = !!opt_data.NamedStreams;
opt_data.VolumeParams.ReadOnlyVolume = !!opt_data.ReadOnlyVolume; opt_data.VolumeParams.ReadOnlyVolume = !!opt_data.ReadOnlyVolume;
f = MemAlloc(sizeof *f); f = fsp_fuse_obj_alloc(env, sizeof *f);
if (0 == f) if (0 == f)
goto fail; goto fail;
memset(f, 0, sizeof *f);
f->env = env; f->env = env;
memcpy(&f->ops, ops, opsize); memcpy(&f->ops, ops, opsize);
@ -496,17 +522,11 @@ FSP_FUSE_API struct fuse *fsp_fuse_new(struct fsp_fuse_env *env,
memcpy(&f->VolumeParams, &opt_data.VolumeParams, sizeof opt_data.VolumeParams); memcpy(&f->VolumeParams, &opt_data.VolumeParams, sizeof opt_data.VolumeParams);
Size = (lstrlenW(ch->MountPoint) + 1) * sizeof(WCHAR); Size = (lstrlenW(ch->MountPoint) + 1) * sizeof(WCHAR);
f->MountPoint = MemAlloc(Size); f->MountPoint = fsp_fuse_obj_alloc(env, Size);
if (0 == f->MountPoint) if (0 == f->MountPoint)
goto fail; goto fail;
memcpy(f->MountPoint, ch->MountPoint, Size); memcpy(f->MountPoint, ch->MountPoint, Size);
Result = FspServiceCreate(FspDiagIdent(), fsp_fuse_svcstart, fsp_fuse_svcstop, 0, &f->Service);
if (!NT_SUCCESS(Result))
goto fail;
FspServiceAllowConsoleMode(f->Service);
f->Service->UserContext = f;
Result = fsp_fuse_preflight(f); Result = fsp_fuse_preflight(f);
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
{ {
@ -554,62 +574,35 @@ FSP_FUSE_API void fsp_fuse_destroy(struct fsp_fuse_env *env,
{ {
fsp_fuse_cleanup(f); fsp_fuse_cleanup(f);
if (0 != f->Service) fsp_fuse_obj_free(f->MountPoint);
FspServiceDelete(f->Service);
MemFree(f->MountPoint); fsp_fuse_obj_free(f);
MemFree(f);
}
static int fsp_fuse_loop_internal(struct fsp_fuse_env *env,
struct fuse *f, FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY GuardStrategy)
{
NTSTATUS Result;
ULONG ExitCode;
f->OpGuardStrategy = GuardStrategy;
Result = FspServiceLoop(f->Service);
ExitCode = FspServiceGetExitCode(f->Service);
if (!NT_SUCCESS(Result))
goto fail;
if (0 != ExitCode)
FspServiceLog(EVENTLOG_WARNING_TYPE,
L"The service %s has exited (ExitCode=%ld).", f->Service->ServiceName, ExitCode);
return 0;
fail:
FspServiceLog(EVENTLOG_ERROR_TYPE,
L"The service %s has failed to run (Status=%lx).", f->Service->ServiceName, Result);
return -1;
} }
FSP_FUSE_API int fsp_fuse_loop(struct fsp_fuse_env *env, FSP_FUSE_API int fsp_fuse_loop(struct fsp_fuse_env *env,
struct fuse *f) struct fuse *f)
{ {
return fsp_fuse_loop_internal(env, f, f->OpGuardStrategy = FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE;
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_COARSE); return 0 == FspServiceRunEx(FspDiagIdent(), fsp_fuse_svcstart, fsp_fuse_svcstop, 0, f) ?
0 : -1;
} }
FSP_FUSE_API int fsp_fuse_loop_mt(struct fsp_fuse_env *env, FSP_FUSE_API int fsp_fuse_loop_mt(struct fsp_fuse_env *env,
struct fuse *f) struct fuse *f)
{ {
return fsp_fuse_loop_internal(env, f, f->OpGuardStrategy = FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE;
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY_FINE); return 0 == FspServiceRunEx(FspDiagIdent(), fsp_fuse_svcstart, fsp_fuse_svcstop, 0, f) ?
0 : -1;
} }
FSP_FUSE_API void fsp_fuse_exit(struct fsp_fuse_env *env, FSP_FUSE_API void fsp_fuse_exit(struct fsp_fuse_env *env,
struct fuse *f) struct fuse *f)
{ {
FspServiceStop(f->Service); if (0 != f->Service)
FspServiceStop(f->Service);
} }
FSP_FUSE_API struct fuse_context *fsp_fuse_get_context(struct fsp_fuse_env *reserved) FSP_FUSE_API struct fuse_context *fsp_fuse_get_context(struct fsp_fuse_env *env)
{ {
struct fuse_context *context; struct fuse_context *context;
@ -622,12 +615,12 @@ FSP_FUSE_API struct fuse_context *fsp_fuse_get_context(struct fsp_fuse_env *rese
{ {
struct fsp_fuse_context_header *contexthdr; struct fsp_fuse_context_header *contexthdr;
contexthdr = MemAlloc(sizeof *contexthdr + sizeof *context); contexthdr = fsp_fuse_obj_alloc(env,
sizeof(struct fsp_fuse_context_header) + sizeof(struct fuse_context));
if (0 == contexthdr) if (0 == contexthdr)
return 0; return 0;
memset(contexthdr, 0, sizeof *contexthdr + sizeof *context); context = FSP_FUSE_CONTEXT_FROM_HDR(contexthdr);
context = (PVOID)contexthdr->ContextBuf;
context->pid = -1; context->pid = -1;
TlsSetValue(fsp_fuse_tlskey, context); TlsSetValue(fsp_fuse_tlskey, context);
@ -664,15 +657,7 @@ FSP_FUSE_API int32_t fsp_fuse_ntstatus_from_errno(struct fsp_fuse_env *env,
/* Cygwin signal support */ /* Cygwin signal support */
static FSP_SERVICE *fsp_fuse_signal_svc;
FSP_FUSE_API void fsp_fuse_signal_handler(int sig) FSP_FUSE_API void fsp_fuse_signal_handler(int sig)
{ {
if (0 != fsp_fuse_signal_svc) FspServiceConsoleCtrlHandler(CTRL_BREAK_EVENT);
FspServiceStop(fsp_fuse_signal_svc);
}
FSP_FUSE_API void fsp_fuse_set_signal_arg(void *se)
{
fsp_fuse_signal_svc = 0 != se ? ((struct fuse *)se)->Service : 0;
} }

View File

@ -20,6 +20,7 @@
NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem, NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
struct fuse *f = FileSystem->UserContext;
struct fuse_context *context; struct fuse_context *context;
struct fsp_fuse_context_header *contexthdr; struct fsp_fuse_context_header *contexthdr;
char *PosixPath = 0; char *PosixPath = 0;
@ -123,7 +124,7 @@ NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem,
goto exit; goto exit;
} }
context = fsp_fuse_get_context(0); context = fsp_fuse_get_context(f->env);
if (0 == context) if (0 == context)
{ {
Result = STATUS_INSUFFICIENT_RESOURCES; Result = STATUS_INSUFFICIENT_RESOURCES;
@ -134,12 +135,12 @@ NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem,
if (!NT_SUCCESS(Result)) if (!NT_SUCCESS(Result))
goto exit; goto exit;
context->fuse = FileSystem->UserContext; context->fuse = f;
context->private_data = context->fuse->data; context->private_data = f->data;
context->uid = Uid; context->uid = Uid;
context->gid = Gid; context->gid = Gid;
contexthdr = (PVOID)((PUINT8)context - sizeof *contexthdr); contexthdr = FSP_FUSE_HDR_FROM_CONTEXT(context);
contexthdr->Request = Request; contexthdr->Request = Request;
contexthdr->Response = Response; contexthdr->Response = Response;
contexthdr->PosixPath = PosixPath; contexthdr->PosixPath = PosixPath;
@ -162,18 +163,19 @@ exit:
NTSTATUS fsp_fuse_op_leave(FSP_FILE_SYSTEM *FileSystem, NTSTATUS fsp_fuse_op_leave(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
{ {
struct fuse *f = FileSystem->UserContext;
struct fuse_context *context; struct fuse_context *context;
struct fsp_fuse_context_header *contexthdr; struct fsp_fuse_context_header *contexthdr;
FspFileSystemOpLeave(FileSystem, Request, Response); FspFileSystemOpLeave(FileSystem, Request, Response);
context = fsp_fuse_get_context(0); context = fsp_fuse_get_context(f->env);
context->fuse = 0; context->fuse = 0;
context->private_data = 0; context->private_data = 0;
context->uid = -1; context->uid = -1;
context->gid = -1; context->gid = -1;
contexthdr = (PVOID)((PUINT8)context - sizeof *contexthdr); contexthdr = FSP_FUSE_HDR_FROM_CONTEXT(context);
if (0 != contexthdr->PosixPath) if (0 != contexthdr->PosixPath)
FspPosixDeletePath(contexthdr->PosixPath); FspPosixDeletePath(contexthdr->PosixPath);
memset(contexthdr, 0, sizeof *contexthdr); memset(contexthdr, 0, sizeof *contexthdr);
@ -349,9 +351,8 @@ static NTSTATUS fsp_fuse_intf_Create(FSP_FILE_SYSTEM *FileSystem,
PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo) PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fuse_context *context = fsp_fuse_get_context(0); struct fuse_context *context = fsp_fuse_get_context(f->env);
struct fsp_fuse_context_header *contexthdr = struct fsp_fuse_context_header *contexthdr = FSP_FUSE_HDR_FROM_CONTEXT(context);
(PVOID)((PUINT8)context - sizeof *contexthdr);
UINT32 Uid, Gid, Mode; UINT32 Uid, Gid, Mode;
FSP_FSCTL_FILE_INFO FileInfoBuf; FSP_FSCTL_FILE_INFO FileInfoBuf;
struct fsp_fuse_file_desc *filedesc = 0; struct fsp_fuse_file_desc *filedesc = 0;
@ -505,7 +506,8 @@ static NTSTATUS fsp_fuse_intf_Open(FSP_FILE_SYSTEM *FileSystem,
PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo) PVOID *PFileNode, FSP_FSCTL_FILE_INFO *FileInfo)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_context_header *contexthdr = fsp_fuse_context_header(); struct fuse_context *context = fsp_fuse_get_context(f->env);
struct fsp_fuse_context_header *contexthdr = FSP_FUSE_HDR_FROM_CONTEXT(context);
UINT32 Uid, Gid, Mode; UINT32 Uid, Gid, Mode;
FSP_FSCTL_FILE_INFO FileInfoBuf; FSP_FSCTL_FILE_INFO FileInfoBuf;
struct fsp_fuse_file_desc *filedesc = 0; struct fsp_fuse_file_desc *filedesc = 0;
@ -1074,7 +1076,8 @@ static NTSTATUS fsp_fuse_intf_Rename(FSP_FILE_SYSTEM *FileSystem,
PWSTR FileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists) PWSTR FileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists)
{ {
struct fuse *f = FileSystem->UserContext; struct fuse *f = FileSystem->UserContext;
struct fsp_fuse_context_header *contexthdr = fsp_fuse_context_header(); struct fuse_context *context = fsp_fuse_get_context(f->env);
struct fsp_fuse_context_header *contexthdr = FSP_FUSE_HDR_FROM_CONTEXT(context);
UINT32 Uid, Gid, Mode; UINT32 Uid, Gid, Mode;
FSP_FSCTL_FILE_INFO FileInfoBuf; FSP_FSCTL_FILE_INFO FileInfoBuf;
struct fsp_fuse_file_desc *filedesc = struct fsp_fuse_file_desc *filedesc =

View File

@ -24,6 +24,11 @@
#define FSP_FUSE_LIBRARY_NAME LIBRARY_NAME "-FUSE" #define FSP_FUSE_LIBRARY_NAME LIBRARY_NAME "-FUSE"
#define FSP_FUSE_HDR_FROM_CONTEXT(c) \
(struct fsp_fuse_context_header *)((PUINT8)(c) - sizeof(struct fsp_fuse_context_header))
#define FSP_FUSE_CONTEXT_FROM_HDR(h) \
(struct fuse_context *)((PUINT8)(h) + sizeof(struct fsp_fuse_context_header))
struct fuse struct fuse
{ {
struct fsp_fuse_env *env; struct fsp_fuse_env *env;
@ -33,9 +38,9 @@ struct fuse
FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY OpGuardStrategy; FSP_FILE_SYSTEM_OPERATION_GUARD_STRATEGY OpGuardStrategy;
FSP_FSCTL_VOLUME_PARAMS VolumeParams; FSP_FSCTL_VOLUME_PARAMS VolumeParams;
PWSTR MountPoint; PWSTR MountPoint;
FSP_SERVICE *Service;
FSP_FILE_SYSTEM *FileSystem; FSP_FILE_SYSTEM *FileSystem;
BOOLEAN fsinit; BOOLEAN fsinit;
FSP_SERVICE *Service; /* weak */
}; };
struct fsp_fuse_context_header struct fsp_fuse_context_header
@ -74,13 +79,6 @@ struct fsp_fuse_dirinfo
char PosixNameBuf[]; /* includes term-0 (unlike FSP_FSCTL_DIR_INFO) */ char PosixNameBuf[]; /* includes term-0 (unlike FSP_FSCTL_DIR_INFO) */
}; };
static inline
struct fsp_fuse_context_header *fsp_fuse_context_header(VOID)
{
struct fuse_context *context = fsp_fuse_get_context(0);
return (PVOID)((PUINT8)context - sizeof(struct fsp_fuse_context_header));
}
NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem, NTSTATUS fsp_fuse_op_enter(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response); FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
NTSTATUS fsp_fuse_op_leave(FSP_FILE_SYSTEM *FileSystem, NTSTATUS fsp_fuse_op_leave(FSP_FILE_SYSTEM *FileSystem,

View File

@ -59,4 +59,6 @@ NTSTATUS FspEventLogUnregister(VOID);
PWSTR FspDiagIdent(VOID); PWSTR FspDiagIdent(VOID);
BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType);
#endif #endif

View File

@ -46,7 +46,7 @@ static VOID FspServiceMain(FSP_SERVICE *Service, DWORD Argc, PWSTR *Argv);
static DWORD WINAPI FspServiceCtrlHandler( static DWORD WINAPI FspServiceCtrlHandler(
DWORD Control, DWORD EventType, PVOID EventData, PVOID Context); DWORD Control, DWORD EventType, PVOID EventData, PVOID Context);
static DWORD WINAPI FspServiceConsoleModeThread(PVOID Context); static DWORD WINAPI FspServiceConsoleModeThread(PVOID Context);
static BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType); BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType);
#define FspServiceFromTable() (0 != FspServiceTable ?\ #define FspServiceFromTable() (0 != FspServiceTable ?\
(FSP_SERVICE *)((PUINT8)FspServiceTable[0].lpServiceName - FIELD_OFFSET(FSP_SERVICE, ServiceName)) :\ (FSP_SERVICE *)((PUINT8)FspServiceTable[0].lpServiceName - FIELD_OFFSET(FSP_SERVICE, ServiceName)) :\
@ -69,10 +69,11 @@ VOID FspServiceFinalize(BOOLEAN Dynamic)
CloseHandle(FspServiceConsoleModeEvent); CloseHandle(FspServiceConsoleModeEvent);
} }
FSP_API ULONG FspServiceRun(PWSTR ServiceName, FSP_API ULONG FspServiceRunEx(PWSTR ServiceName,
FSP_SERVICE_START *OnStart, FSP_SERVICE_START *OnStart,
FSP_SERVICE_STOP *OnStop, FSP_SERVICE_STOP *OnStop,
FSP_SERVICE_CONTROL *OnControl) FSP_SERVICE_CONTROL *OnControl,
PVOID UserContext)
{ {
FSP_SERVICE *Service; FSP_SERVICE *Service;
NTSTATUS Result; NTSTATUS Result;
@ -85,6 +86,7 @@ FSP_API ULONG FspServiceRun(PWSTR ServiceName,
L"The service %s cannot be created (Status=%lx).", Service->ServiceName, Result); L"The service %s cannot be created (Status=%lx).", Service->ServiceName, Result);
return FspWin32FromNtStatus(Result); return FspWin32FromNtStatus(Result);
} }
Service->UserContext = UserContext;
FspServiceAllowConsoleMode(Service); FspServiceAllowConsoleMode(Service);
Result = FspServiceLoop(Service); Result = FspServiceLoop(Service);
@ -510,7 +512,8 @@ static DWORD WINAPI FspServiceConsoleModeThread(PVOID Context)
return 0; return 0;
} }
static BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType) /* expose FspServiceConsoleCtrlHandler so it can be used from fsp_fuse_signal_handler */
BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType)
{ {
UINT32 Disabled = FspServiceConsoleCtrlHandlerDisabled; UINT32 Disabled = FspServiceConsoleCtrlHandlerDisabled;
MemoryBarrier(); MemoryBarrier();