mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-25 01:42:24 -05:00
launcher: named pipe implementation
This commit is contained in:
parent
e82b06ae49
commit
c32d05c3b6
@ -176,6 +176,7 @@
|
|||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\..\src\launcher\launcher.h" />
|
||||||
<ClInclude Include="..\..\..\src\shared\minimal.h" />
|
<ClInclude Include="..\..\..\src\shared\minimal.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
@ -21,5 +21,8 @@
|
|||||||
<ClInclude Include="..\..\..\src\shared\minimal.h">
|
<ClInclude Include="..\..\..\src\shared\minimal.h">
|
||||||
<Filter>Include\shared</Filter>
|
<Filter>Include\shared</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\src\launcher\launcher.h">
|
||||||
|
<Filter>Source</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -15,9 +15,7 @@
|
|||||||
* software.
|
* software.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <winfsp/winfsp.h>
|
#include <launcher/launcher.h>
|
||||||
#include <shared/minimal.h>
|
|
||||||
#include <sddl.h>
|
|
||||||
|
|
||||||
#define PROGNAME "WinFsp-Launcher"
|
#define PROGNAME "WinFsp-Launcher"
|
||||||
#define REGKEY "SYSTEM\\CurrentControlSet\\Services\\" PROGNAME "\\Services"
|
#define REGKEY "SYSTEM\\CurrentControlSet\\Services\\" PROGNAME "\\Services"
|
||||||
@ -282,18 +280,171 @@ VOID SvcInstanceStop(PWSTR InstanceName)
|
|||||||
LeaveCriticalSection(&SvcInstanceLock);
|
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)
|
static NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
||||||
{
|
{
|
||||||
InitializeCriticalSection(&SvcInstanceLock);
|
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;
|
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)
|
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);
|
DeleteCriticalSection(&SvcInstanceLock);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
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)
|
int wmain(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
ProcessHeap = GetProcessHeap();
|
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