mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-24 09:23:37 -05:00
launcher: named pipe implementation
This commit is contained in:
parent
e82b06ae49
commit
c32d05c3b6
@ -176,6 +176,7 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\src\launcher\launcher.h" />
|
||||
<ClInclude Include="..\..\..\src\shared\minimal.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
@ -21,5 +21,8 @@
|
||||
<ClInclude Include="..\..\..\src\shared\minimal.h">
|
||||
<Filter>Include\shared</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\launcher\launcher.h">
|
||||
<Filter>Source</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -15,9 +15,7 @@
|
||||
* software.
|
||||
*/
|
||||
|
||||
#include <winfsp/winfsp.h>
|
||||
#include <shared/minimal.h>
|
||||
#include <sddl.h>
|
||||
#include <launcher/launcher.h>
|
||||
|
||||
#define PROGNAME "WinFsp-Launcher"
|
||||
#define REGKEY "SYSTEM\\CurrentControlSet\\Services\\" PROGNAME "\\Services"
|
||||
@ -282,18 +280,171 @@ VOID SvcInstanceStop(PWSTR InstanceName)
|
||||
LeaveCriticalSection(&SvcInstanceLock);
|
||||
}
|
||||
|
||||
static HANDLE SvcThread, SvcEvent;
|
||||
static HANDLE SvcPipe = INVALID_HANDLE_VALUE;
|
||||
static OVERLAPPED SvcOverlapped;
|
||||
|
||||
static DWORD WINAPI SvcPipeServer(PVOID Context);
|
||||
|
||||
static NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
||||
{
|
||||
InitializeCriticalSection(&SvcInstanceLock);
|
||||
|
||||
SvcEvent = CreateEventW(0, TRUE, FALSE, 0);
|
||||
if (0 == SvcEvent)
|
||||
goto fail;
|
||||
|
||||
SvcOverlapped.hEvent = CreateEventW(0, TRUE, FALSE, 0);
|
||||
if (0 == SvcOverlapped.hEvent)
|
||||
goto fail;
|
||||
|
||||
SvcPipe = CreateNamedPipeW(L"" 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, PIPE_SRVBUF_SIZE, PIPE_CLIBUF_SIZE, 0, 0);
|
||||
if (INVALID_HANDLE_VALUE == SvcPipe)
|
||||
goto fail;
|
||||
|
||||
SvcThread = CreateThread(0, 0, SvcPipeServer, Service, 0, 0);
|
||||
if (0 == SvcThread)
|
||||
goto fail;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
fail:
|
||||
DWORD LastError = GetLastError();
|
||||
|
||||
if (0 != SvcThread)
|
||||
CloseHandle(SvcThread);
|
||||
|
||||
if (INVALID_HANDLE_VALUE != SvcPipe)
|
||||
CloseHandle(SvcPipe);
|
||||
|
||||
if (0 != SvcOverlapped.hEvent)
|
||||
CloseHandle(SvcOverlapped.hEvent);
|
||||
|
||||
if (0 != SvcEvent)
|
||||
CloseHandle(SvcEvent);
|
||||
|
||||
DeleteCriticalSection(&SvcInstanceLock);
|
||||
|
||||
return FspNtStatusFromWin32(LastError);
|
||||
}
|
||||
|
||||
static NTSTATUS SvcStop(FSP_SERVICE *Service)
|
||||
{
|
||||
SetEvent(SvcEvent);
|
||||
FspServiceRequestTime(Service, 4500); /* just under 5 sec */
|
||||
WaitForSingleObject(SvcThread, 4500);
|
||||
|
||||
if (0 != SvcThread)
|
||||
CloseHandle(SvcThread);
|
||||
|
||||
if (INVALID_HANDLE_VALUE != SvcPipe)
|
||||
CloseHandle(SvcPipe);
|
||||
|
||||
if (0 != SvcOverlapped.hEvent)
|
||||
CloseHandle(SvcOverlapped.hEvent);
|
||||
|
||||
if (0 != SvcEvent)
|
||||
CloseHandle(SvcEvent);
|
||||
|
||||
DeleteCriticalSection(&SvcInstanceLock);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline DWORD SvcPipeWaitResult(BOOL Success, HANDLE StopEvent,
|
||||
HANDLE Handle, OVERLAPPED *Overlapped, PDWORD PBytesTransferred)
|
||||
{
|
||||
HANDLE WaitObjects[2];
|
||||
DWORD WaitResult;
|
||||
|
||||
if (!Success && ERROR_IO_PENDING != GetLastError())
|
||||
return GetLastError();
|
||||
|
||||
WaitObjects[0] = StopEvent;
|
||||
WaitObjects[1] = Overlapped->hEvent;
|
||||
WaitResult = WaitForMultipleObjects(2, WaitObjects, FALSE, INFINITE);
|
||||
if (WAIT_OBJECT_0 == WaitResult)
|
||||
return -1; /* special: stop thread */
|
||||
else if (WAIT_OBJECT_0 + 1 == WaitResult)
|
||||
{
|
||||
if (!GetOverlappedResult(Handle, Overlapped, PBytesTransferred, TRUE))
|
||||
return GetLastError();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
static DWORD WINAPI SvcPipeServer(PVOID Context)
|
||||
{
|
||||
FSP_SERVICE *Service = Context;
|
||||
PWSTR PipeBuf = 0;
|
||||
DWORD LastError, BytesTransferred;
|
||||
|
||||
PipeBuf = MemAlloc(PIPE_SRVBUF_SIZE);
|
||||
if (0 == PipeBuf)
|
||||
{
|
||||
FspServiceSetExitCode(Service, ERROR_NO_SYSTEM_RESOURCES);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
LastError = SvcPipeWaitResult(
|
||||
ConnectNamedPipe(SvcPipe, &SvcOverlapped),
|
||||
SvcEvent, SvcPipe, &SvcOverlapped, &BytesTransferred);
|
||||
if (-1 == LastError)
|
||||
break;
|
||||
else if (ERROR_PIPE_CONNECTED != LastError && ERROR_NO_DATA != LastError)
|
||||
{
|
||||
FspServiceLog(EVENTLOG_WARNING_TYPE,
|
||||
L"Error in service main loop (ConnectNamedPipe = %ld). Continuing...", LastError);
|
||||
continue;
|
||||
}
|
||||
|
||||
LastError = SvcPipeWaitResult(
|
||||
ReadFile(SvcPipe, PipeBuf, PIPE_SRVBUF_SIZE, &BytesTransferred, &SvcOverlapped),
|
||||
SvcEvent, SvcPipe, &SvcOverlapped, &BytesTransferred);
|
||||
if (-1 == LastError)
|
||||
break;
|
||||
else if (0 != LastError)
|
||||
{
|
||||
DisconnectNamedPipe(SvcPipe);
|
||||
FspServiceLog(EVENTLOG_WARNING_TYPE,
|
||||
L"Error in service main loop (ReadFile = %ld). Continuing...", LastError);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* handle PipeBuf */
|
||||
|
||||
LastError = SvcPipeWaitResult(
|
||||
WriteFile(SvcPipe, PipeBuf, PIPE_SRVBUF_SIZE, &BytesTransferred, &SvcOverlapped),
|
||||
SvcEvent, SvcPipe, &SvcOverlapped, &BytesTransferred);
|
||||
if (-1 == LastError)
|
||||
break;
|
||||
else if (0 != LastError)
|
||||
{
|
||||
DisconnectNamedPipe(SvcPipe);
|
||||
FspServiceLog(EVENTLOG_WARNING_TYPE,
|
||||
L"Error in service main loop (WriteFile = %ld). Continuing...", LastError);
|
||||
continue;
|
||||
}
|
||||
|
||||
DisconnectNamedPipe(SvcPipe);
|
||||
}
|
||||
|
||||
exit:
|
||||
MemFree(PipeBuf);
|
||||
|
||||
FspServiceStop(Service);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wmain(int argc, wchar_t **argv)
|
||||
{
|
||||
ProcessHeap = GetProcessHeap();
|
||||
|
29
src/launcher/launcher.h
Normal file
29
src/launcher/launcher.h
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @file launcher/launcher.h
|
||||
*
|
||||
* @copyright 2015-2016 Bill Zissimopoulos
|
||||
*/
|
||||
/*
|
||||
* This file is part of WinFsp.
|
||||
*
|
||||
* You can redistribute it and/or modify it under the terms of the
|
||||
* GNU Affero 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 <winfsp/winfsp.h>
|
||||
#include <shared/minimal.h>
|
||||
|
||||
#define PIPE_NAME "\\\\.\\pipe\\WinFsp.{14E7137D-22B4-437A-B0C1-D21D1BDF3767}"
|
||||
#define PIPE_SRVBUF_SIZE 1024
|
||||
#define PIPE_CLIBUF_SIZE 1024
|
||||
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user