mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 08:53:01 -05:00
memfs: convert to service
This commit is contained in:
parent
3d2a2dd90d
commit
077bbb0d65
@ -874,6 +874,7 @@ FSP_API VOID FspServiceAllowConsoleMode(FSP_SERVICE *Service);
|
|||||||
FSP_API VOID FspServiceAcceptControl(FSP_SERVICE *Service, ULONG Control);
|
FSP_API VOID FspServiceAcceptControl(FSP_SERVICE *Service, ULONG Control);
|
||||||
FSP_API VOID FspServiceRequestTime(FSP_SERVICE *Service, ULONG Time);
|
FSP_API VOID FspServiceRequestTime(FSP_SERVICE *Service, ULONG Time);
|
||||||
FSP_API VOID FspServiceSetExitCode(FSP_SERVICE *Service, ULONG ExitCode);
|
FSP_API VOID FspServiceSetExitCode(FSP_SERVICE *Service, ULONG ExitCode);
|
||||||
|
FSP_API ULONG FspServiceGetExitCode(FSP_SERVICE *Service);
|
||||||
FSP_API NTSTATUS FspServiceRun(FSP_SERVICE *Service);
|
FSP_API NTSTATUS FspServiceRun(FSP_SERVICE *Service);
|
||||||
FSP_API VOID FspServiceStop(FSP_SERVICE *Service);
|
FSP_API VOID FspServiceStop(FSP_SERVICE *Service);
|
||||||
FSP_API BOOLEAN FspServiceIsInteractive(VOID);
|
FSP_API BOOLEAN FspServiceIsInteractive(VOID);
|
||||||
|
@ -173,6 +173,11 @@ FSP_API VOID FspServiceSetExitCode(FSP_SERVICE *Service, ULONG ExitCode)
|
|||||||
Service->ExitCode = ExitCode;
|
Service->ExitCode = ExitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API ULONG FspServiceGetExitCode(FSP_SERVICE *Service)
|
||||||
|
{
|
||||||
|
return Service->ServiceStatus.dwWin32ExitCode;
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspServiceRun(FSP_SERVICE *Service)
|
FSP_API NTSTATUS FspServiceRun(FSP_SERVICE *Service)
|
||||||
{
|
{
|
||||||
SERVICE_TABLE_ENTRYW ServiceTable[2];
|
SERVICE_TABLE_ENTRYW ServiceTable[2];
|
||||||
@ -301,13 +306,10 @@ static VOID FspServiceMain(FSP_SERVICE *Service, DWORD Argc, PWSTR *Argv)
|
|||||||
SERVICE_STATUS ServiceStatus;
|
SERVICE_STATUS ServiceStatus;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
|
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
|
||||||
ServiceStatus.dwControlsAccepted = 0;
|
ServiceStatus.dwControlsAccepted = 0;
|
||||||
ServiceStatus.dwCheckPoint = 0;
|
|
||||||
ServiceStatus.dwWaitHint = 0;
|
|
||||||
FspServiceSetStatus(Service,
|
FspServiceSetStatus(Service,
|
||||||
SetStatus_CurrentState | SetStatus_ControlsAccepted | SetStatus_CheckPoint | SetStatus_WaitHint,
|
SetStatus_CurrentState | SetStatus_ControlsAccepted, &ServiceStatus);
|
||||||
&ServiceStatus);
|
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
if (0 != Service->OnStart)
|
if (0 != Service->OnStart)
|
||||||
|
@ -20,46 +20,111 @@
|
|||||||
|
|
||||||
#define PROGNAME "memfs"
|
#define PROGNAME "memfs"
|
||||||
|
|
||||||
static void vwarn(const char *format, va_list ap)
|
#define info(format, ...) FspServiceLog(EVENTLOG_INFORMATION_TYPE, format, __VA_ARGS__)
|
||||||
|
#define warn(format, ...) FspServiceLog(EVENTLOG_WARNING_TYPE, format, __VA_ARGS__)
|
||||||
|
#define fail(format, ...) FspServiceLog(EVENTLOG_ERROR_TYPE, format, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define fatal(format, ...) (fail(format, __VA_ARGS__), exit(ERROR_GEN_FAILURE))
|
||||||
|
|
||||||
|
#define argtos(v) if (arge > ++argp) v = *argp; else goto usage
|
||||||
|
#define argtol(v) if (arge > ++argp) v = wcstol_deflt(*argp, v); else goto usage
|
||||||
|
|
||||||
|
static ULONG wcstol_deflt(wchar_t *w, ULONG deflt)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
wchar_t *endp;
|
||||||
/* wvsprintf is only safe with a 1024 byte buffer */
|
ULONG ul = wcstol(w, &endp, 10);
|
||||||
DWORD BytesTransferred;
|
return L'\0' != w[0] && L'\0' == *endp ? ul : deflt;
|
||||||
|
|
||||||
wvsprintfA(buf, format, ap);
|
|
||||||
buf[sizeof buf - 1] = '\0';
|
|
||||||
|
|
||||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE),
|
|
||||||
buf, (DWORD)strlen(buf),
|
|
||||||
&BytesTransferred, 0);
|
|
||||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE),
|
|
||||||
"\n", 1,
|
|
||||||
&BytesTransferred, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void warn(const char *format, ...)
|
NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
||||||
{
|
{
|
||||||
va_list ap;
|
wchar_t **argp, **arge;
|
||||||
|
ULONG Flags = MemfsDisk;
|
||||||
|
ULONG FileInfoTimeout = INFINITE;
|
||||||
|
ULONG MaxFileNodes = 1024;
|
||||||
|
ULONG MaxFileSize = 16 * 1024 * 1024;
|
||||||
|
PWSTR MountPoint = 0;
|
||||||
|
PWSTR VolumePrefix = 0;
|
||||||
|
PWSTR RootSddl = 0;
|
||||||
|
MEMFS *Memfs;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
va_start(ap, format);
|
for (argp = argv + 1, arge = argv + argc; arge > argp; argp++)
|
||||||
vwarn(format, ap);
|
{
|
||||||
va_end(ap);
|
if (L'-' != argp[0][0])
|
||||||
|
break;
|
||||||
|
switch (argp[0][1])
|
||||||
|
{
|
||||||
|
case L'?':
|
||||||
|
goto usage;
|
||||||
|
case L'm':
|
||||||
|
argtos(MountPoint);
|
||||||
|
break;
|
||||||
|
case L'n':
|
||||||
|
argtol(MaxFileNodes);
|
||||||
|
break;
|
||||||
|
case L'S':
|
||||||
|
argtos(RootSddl);
|
||||||
|
break;
|
||||||
|
case L's':
|
||||||
|
argtol(MaxFileSize);
|
||||||
|
break;
|
||||||
|
case L't':
|
||||||
|
argtol(FileInfoTimeout);
|
||||||
|
break;
|
||||||
|
case L'u':
|
||||||
|
argtos(VolumePrefix);
|
||||||
|
Flags = MemfsNet;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fail(const char *format, ...)
|
if (arge > argp)
|
||||||
|
goto usage;
|
||||||
|
|
||||||
|
Result = MemfsCreate(Flags, FileInfoTimeout, MaxFileNodes, MaxFileSize, VolumePrefix, RootSddl,
|
||||||
|
&Memfs);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
va_list ap;
|
fail(L"cannot create MEMFS");
|
||||||
|
goto exit;
|
||||||
va_start(ap, format);
|
|
||||||
vwarn(format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usage(void)
|
Result = FspFileSystemSetMountPoint(MemfsFileSystem(Memfs), MountPoint);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
static char usage[] = ""
|
fail(L"cannot mount MEMFS");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = MemfsStart(Memfs);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
fail(L"cannot start MEMFS");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
MountPoint = FspFileSystemMountPoint(MemfsFileSystem(Memfs));
|
||||||
|
|
||||||
|
Service->UserContext = Memfs;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
info(L"%s -t %ld -n %ld -s %ld%s%s%s%s -m %s",
|
||||||
|
L"" PROGNAME, FileInfoTimeout, MaxFileNodes, MaxFileSize,
|
||||||
|
RootSddl ? L" -S " : L"", RootSddl ? RootSddl : L"",
|
||||||
|
VolumePrefix ? L" -u " : L"", VolumePrefix ? VolumePrefix : L"",
|
||||||
|
MountPoint);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Result) && 0 != Memfs)
|
||||||
|
MemfsDelete(Memfs);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
usage:
|
||||||
|
static wchar_t usage[] = L""
|
||||||
"usage: %s OPTIONS\n"
|
"usage: %s OPTIONS\n"
|
||||||
"\n"
|
"\n"
|
||||||
"options:\n"
|
"options:\n"
|
||||||
@ -70,118 +135,38 @@ static void usage(void)
|
|||||||
" -u \\Server\\Share [UNC prefix (single backslash)]\n"
|
" -u \\Server\\Share [UNC prefix (single backslash)]\n"
|
||||||
" -m MountPoint [X:]\n";
|
" -m MountPoint [X:]\n";
|
||||||
|
|
||||||
warn(usage, PROGNAME);
|
fail(usage, L"" PROGNAME);
|
||||||
exit(2);
|
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG argtol(wchar_t **argp, ULONG deflt)
|
NTSTATUS SvcStop(FSP_SERVICE *Service)
|
||||||
{
|
{
|
||||||
if (0 == argp[0])
|
MEMFS *Memfs = Service->UserContext;
|
||||||
usage();
|
|
||||||
|
|
||||||
wchar_t *endp;
|
MemfsStop(Memfs);
|
||||||
ULONG ul = wcstol(argp[0], &endp, 10);
|
MemfsDelete(Memfs);
|
||||||
return L'\0' != argp[0][0] && L'\0' == *endp ? ul : deflt;
|
|
||||||
}
|
|
||||||
|
|
||||||
static wchar_t *argtos(wchar_t **argp)
|
return STATUS_SUCCESS;
|
||||||
{
|
|
||||||
if (0 == argp[0])
|
|
||||||
usage();
|
|
||||||
|
|
||||||
return argp[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
static HANDLE MainEvent;
|
|
||||||
|
|
||||||
static BOOL WINAPI ConsoleCtrlHandler(DWORD CtrlType)
|
|
||||||
{
|
|
||||||
SetEvent(MainEvent);
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int wmain(int argc, wchar_t **argv)
|
int wmain(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
wchar_t **argp;
|
FSP_SERVICE *Service;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
MEMFS *Memfs;
|
ULONG ExitCode;
|
||||||
ULONG Flags = MemfsDisk;
|
|
||||||
ULONG FileInfoTimeout = INFINITE;
|
|
||||||
ULONG MaxFileNodes = 1024;
|
|
||||||
ULONG MaxFileSize = 16 * 1024 * 1024;
|
|
||||||
PWSTR MountPoint = 0;
|
|
||||||
PWSTR VolumePrefix = 0;
|
|
||||||
PWSTR RootSddl = 0;
|
|
||||||
|
|
||||||
for (argp = argv + 1; 0 != argp[0]; argp++)
|
Result = FspServiceCreate(L"" PROGNAME, SvcStart, SvcStop, 0, &Service);
|
||||||
{
|
|
||||||
if (L'-' != argp[0][0])
|
|
||||||
break;
|
|
||||||
switch (argp[0][1])
|
|
||||||
{
|
|
||||||
case L'?':
|
|
||||||
usage();
|
|
||||||
break;
|
|
||||||
case L'm':
|
|
||||||
MountPoint = argtos(++argp);
|
|
||||||
break;
|
|
||||||
case L'n':
|
|
||||||
MaxFileNodes = argtol(++argp, MaxFileNodes);
|
|
||||||
break;
|
|
||||||
case L'S':
|
|
||||||
RootSddl = argtos(++argp);
|
|
||||||
break;
|
|
||||||
case L's':
|
|
||||||
MaxFileSize = argtol(++argp, MaxFileSize);
|
|
||||||
break;
|
|
||||||
case L't':
|
|
||||||
FileInfoTimeout = argtol(++argp, FileInfoTimeout);
|
|
||||||
break;
|
|
||||||
case L'u':
|
|
||||||
VolumePrefix = argtos(++argp);
|
|
||||||
Flags = MemfsNet;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != argp[0])
|
|
||||||
usage();
|
|
||||||
|
|
||||||
MainEvent = CreateEvent(0, TRUE, FALSE, 0);
|
|
||||||
if (0 == MainEvent)
|
|
||||||
fail("error: cannot create MainEvent");
|
|
||||||
|
|
||||||
Result = MemfsCreate(Flags, FileInfoTimeout, MaxFileNodes, MaxFileSize, VolumePrefix, RootSddl,
|
|
||||||
&Memfs);
|
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
fail("error: cannot create MEMFS");
|
fatal(L"cannot create service (Status=%lx)", Result);
|
||||||
Result = MemfsStart(Memfs);
|
|
||||||
|
FspServiceAllowConsoleMode(Service);
|
||||||
|
Result = FspServiceRun(Service);
|
||||||
|
ExitCode = FspServiceGetExitCode(Service);
|
||||||
|
FspServiceDelete(Service);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
fail("error: cannot start MEMFS");
|
fatal(L"cannot run service (Status=%lx)", Result);
|
||||||
Result = FspFileSystemSetMountPoint(MemfsFileSystem(Memfs), MountPoint);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
fail("error: cannot mount MEMFS");
|
|
||||||
MountPoint = FspFileSystemMountPoint(MemfsFileSystem(Memfs));
|
|
||||||
|
|
||||||
warn("%s -t %ld -n %ld -s %ld%s%S%s%S -m %S",
|
return ExitCode;
|
||||||
PROGNAME, FileInfoTimeout, MaxFileNodes, MaxFileSize,
|
|
||||||
RootSddl ? " -S " : "", RootSddl ? RootSddl : L"",
|
|
||||||
VolumePrefix ? " -u " : "", VolumePrefix ? VolumePrefix : L"",
|
|
||||||
MountPoint);
|
|
||||||
SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
|
|
||||||
if (WAIT_OBJECT_0 != WaitForSingleObject(MainEvent, INFINITE))
|
|
||||||
fail("error: cannot wait on MainEvent");
|
|
||||||
|
|
||||||
FspFileSystemRemoveMountPoint(MemfsFileSystem(Memfs));
|
|
||||||
MemfsStop(Memfs);
|
|
||||||
MemfsDelete(Memfs);
|
|
||||||
|
|
||||||
/* the OS will handle this! */
|
|
||||||
// CloseHandle(MainEvent);
|
|
||||||
// MainEvent = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user