mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
launcher: named pipe implementation
This commit is contained in:
parent
c32d05c3b6
commit
528cbd3295
@ -285,6 +285,7 @@ static HANDLE SvcPipe = INVALID_HANDLE_VALUE;
|
|||||||
static OVERLAPPED SvcOverlapped;
|
static OVERLAPPED SvcOverlapped;
|
||||||
|
|
||||||
static DWORD WINAPI SvcPipeServer(PVOID Context);
|
static DWORD WINAPI SvcPipeServer(PVOID Context);
|
||||||
|
static VOID SvcPipeTransact(PWSTR PipeBuf, PULONG PSize);
|
||||||
|
|
||||||
static NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
static NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
||||||
{
|
{
|
||||||
@ -381,6 +382,10 @@ static inline DWORD SvcPipeWaitResult(BOOL Success, HANDLE StopEvent,
|
|||||||
|
|
||||||
static DWORD WINAPI SvcPipeServer(PVOID Context)
|
static DWORD WINAPI SvcPipeServer(PVOID Context)
|
||||||
{
|
{
|
||||||
|
static PWSTR LoopErrorMessage =
|
||||||
|
L"Error in service main loop (%s = %ld). Exiting...";
|
||||||
|
static PWSTR LoopWarningMessage =
|
||||||
|
L"Error in service main loop (%s = %ld). Continuing...";
|
||||||
FSP_SERVICE *Service = Context;
|
FSP_SERVICE *Service = Context;
|
||||||
PWSTR PipeBuf = 0;
|
PWSTR PipeBuf = 0;
|
||||||
DWORD LastError, BytesTransferred;
|
DWORD LastError, BytesTransferred;
|
||||||
@ -401,8 +406,8 @@ static DWORD WINAPI SvcPipeServer(PVOID Context)
|
|||||||
break;
|
break;
|
||||||
else if (ERROR_PIPE_CONNECTED != LastError && ERROR_NO_DATA != LastError)
|
else if (ERROR_PIPE_CONNECTED != LastError && ERROR_NO_DATA != LastError)
|
||||||
{
|
{
|
||||||
FspServiceLog(EVENTLOG_WARNING_TYPE,
|
FspServiceLog(EVENTLOG_WARNING_TYPE, LoopWarningMessage,
|
||||||
L"Error in service main loop (ConnectNamedPipe = %ld). Continuing...", LastError);
|
L"ConnectNamedPipe", LastError);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,26 +416,46 @@ static DWORD WINAPI SvcPipeServer(PVOID Context)
|
|||||||
SvcEvent, SvcPipe, &SvcOverlapped, &BytesTransferred);
|
SvcEvent, SvcPipe, &SvcOverlapped, &BytesTransferred);
|
||||||
if (-1 == LastError)
|
if (-1 == LastError)
|
||||||
break;
|
break;
|
||||||
else if (0 != LastError)
|
else if (0 != LastError || sizeof(WCHAR) <= BytesTransferred)
|
||||||
{
|
{
|
||||||
DisconnectNamedPipe(SvcPipe);
|
DisconnectNamedPipe(SvcPipe);
|
||||||
FspServiceLog(EVENTLOG_WARNING_TYPE,
|
if (0 != LastError)
|
||||||
L"Error in service main loop (ReadFile = %ld). Continuing...", LastError);
|
FspServiceLog(EVENTLOG_WARNING_TYPE, LoopWarningMessage,
|
||||||
|
L"ReadFile", LastError);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle PipeBuf */
|
if (!ImpersonateNamedPipeClient(SvcPipe))
|
||||||
|
{
|
||||||
|
LastError = GetLastError();
|
||||||
|
DisconnectNamedPipe(SvcPipe);
|
||||||
|
FspServiceLog(EVENTLOG_WARNING_TYPE, LoopWarningMessage,
|
||||||
|
L"ImpersonateNamedPipeClient", LastError);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SvcPipeTransact(PipeBuf, &BytesTransferred);
|
||||||
|
|
||||||
|
if (!RevertToSelf())
|
||||||
|
{
|
||||||
|
LastError = GetLastError();
|
||||||
|
DisconnectNamedPipe(SvcPipe);
|
||||||
|
FspServiceLog(EVENTLOG_ERROR_TYPE, LoopErrorMessage,
|
||||||
|
L"RevertToSelf", LastError);
|
||||||
|
FspServiceSetExitCode(Service, LastError);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
LastError = SvcPipeWaitResult(
|
LastError = SvcPipeWaitResult(
|
||||||
WriteFile(SvcPipe, PipeBuf, PIPE_SRVBUF_SIZE, &BytesTransferred, &SvcOverlapped),
|
WriteFile(SvcPipe, PipeBuf, BytesTransferred, &BytesTransferred, &SvcOverlapped),
|
||||||
SvcEvent, SvcPipe, &SvcOverlapped, &BytesTransferred);
|
SvcEvent, SvcPipe, &SvcOverlapped, &BytesTransferred);
|
||||||
if (-1 == LastError)
|
if (-1 == LastError)
|
||||||
break;
|
break;
|
||||||
else if (0 != LastError)
|
else if (0 != LastError)
|
||||||
{
|
{
|
||||||
DisconnectNamedPipe(SvcPipe);
|
DisconnectNamedPipe(SvcPipe);
|
||||||
FspServiceLog(EVENTLOG_WARNING_TYPE,
|
FspServiceLog(EVENTLOG_WARNING_TYPE, LoopWarningMessage,
|
||||||
L"Error in service main loop (WriteFile = %ld). Continuing...", LastError);
|
L"WriteFile", LastError);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,6 +470,75 @@ exit:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline PWSTR SvcPipeTransactGetPart(PWSTR *PP, PWSTR PipeBufEnd)
|
||||||
|
{
|
||||||
|
PWSTR PipeBufBeg = *PP, P;
|
||||||
|
|
||||||
|
for (P = PipeBufBeg; PipeBufEnd > P && *P; P++)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (PipeBufEnd > P)
|
||||||
|
{
|
||||||
|
*PP = P + 1;
|
||||||
|
return PipeBufBeg;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*PP = P;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID SvcPipeTransact(PWSTR PipeBuf, PULONG PSize)
|
||||||
|
{
|
||||||
|
if (sizeof(WCHAR) > *PSize)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PWSTR P = PipeBuf, PipeBufEnd = PipeBuf + *PSize / sizeof(WCHAR);
|
||||||
|
PWSTR ClassName, InstanceName;
|
||||||
|
ULONG Argc; PWSTR Argv[10];
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
*PSize = 0;
|
||||||
|
|
||||||
|
switch (*P++)
|
||||||
|
{
|
||||||
|
case LauncherSvcInstanceStart:
|
||||||
|
ClassName = SvcPipeTransactGetPart(&P, PipeBufEnd);
|
||||||
|
InstanceName = SvcPipeTransactGetPart(&P, PipeBufEnd);
|
||||||
|
for (Argc = 0; 10 > Argc; Argc++)
|
||||||
|
if (0 == (Argv[Argc] = SvcPipeTransactGetPart(&P, PipeBufEnd)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
Result = STATUS_UNSUCCESSFUL;
|
||||||
|
if (0 != ClassName && 0 != InstanceName)
|
||||||
|
Result = SvcInstanceStart(ClassName, InstanceName, Argc, Argv);
|
||||||
|
|
||||||
|
*PipeBuf = NT_SUCCESS(Result) ? L'+' : L'-';
|
||||||
|
*PSize = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LauncherSvcInstanceStop:
|
||||||
|
InstanceName = SvcPipeTransactGetPart(&P, PipeBufEnd);
|
||||||
|
if (0 != InstanceName)
|
||||||
|
SvcInstanceStop(InstanceName);
|
||||||
|
|
||||||
|
*PipeBuf = L'+';
|
||||||
|
*PSize = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LauncherSvcInstanceList:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LauncherSvcInstanceInfo:
|
||||||
|
InstanceName = SvcPipeTransactGetPart(&P, PipeBufEnd);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int wmain(int argc, wchar_t **argv)
|
int wmain(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
ProcessHeap = GetProcessHeap();
|
ProcessHeap = GetProcessHeap();
|
||||||
|
@ -25,5 +25,12 @@
|
|||||||
#define PIPE_SRVBUF_SIZE 1024
|
#define PIPE_SRVBUF_SIZE 1024
|
||||||
#define PIPE_CLIBUF_SIZE 1024
|
#define PIPE_CLIBUF_SIZE 1024
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
LauncherSvcInstanceStart = 'S',
|
||||||
|
LauncherSvcInstanceStop = 'T',
|
||||||
|
LauncherSvcInstanceList = 'L',
|
||||||
|
LauncherSvcInstanceInfo = 'I',
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user