winfsp/tst/memfs/memfs-main.c
Bill Zissimopoulos 3ed7847d84 tst: test case insensitivity
sys: FspFileNameIsValid: $DATA is case insensitive
2016-10-15 19:50:47 -07:00

210 lines
5.7 KiB
C

/**
* @file memfs-main.c
*
* @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
* 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.
*/
#include <winfsp/winfsp.h>
#include "memfs.h"
#define PROGNAME "memfs"
#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 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)
{
wchar_t *endp;
ULONG ul = wcstol(w, &endp, 0);
return L'\0' != w[0] && L'\0' == *endp ? ul : deflt;
}
NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
{
wchar_t **argp, **arge;
ULONG DebugFlags = 0;
PWSTR DebugLogFile = 0;
ULONG CaseInsensitiveFlags = 0;
ULONG Flags = MemfsDisk;
ULONG FileInfoTimeout = INFINITE;
ULONG MaxFileNodes = 1024;
ULONG MaxFileSize = 16 * 1024 * 1024;
PWSTR MountPoint = 0;
PWSTR VolumePrefix = 0;
PWSTR RootSddl = 0;
HANDLE DebugLogHandle = INVALID_HANDLE_VALUE;
MEMFS *Memfs = 0;
NTSTATUS Result;
for (argp = argv + 1, arge = argv + argc; arge > argp; argp++)
{
if (L'-' != argp[0][0])
break;
switch (argp[0][1])
{
case L'?':
goto usage;
case L'd':
argtol(DebugFlags);
break;
case L'D':
argtos(DebugLogFile);
break;
case L'i':
CaseInsensitiveFlags = MemfsCaseInsensitive;
break;
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);
if (0 != VolumePrefix && L'\0' != VolumePrefix[0])
Flags = MemfsNet;
break;
default:
goto usage;
}
}
if (arge > argp)
goto usage;
if (MemfsDisk == Flags && 0 == MountPoint)
goto usage;
if (0 != DebugLogFile)
{
if (0 == wcscmp(L"-", DebugLogFile))
DebugLogHandle = GetStdHandle(STD_OUTPUT_HANDLE);
else
DebugLogHandle = CreateFileW(
DebugLogFile,
FILE_APPEND_DATA,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
if (INVALID_HANDLE_VALUE == DebugLogHandle)
{
fail(L"cannot open debug log file");
goto usage;
}
FspDebugLogSetHandle(DebugLogHandle);
}
Result = MemfsCreate(
CaseInsensitiveFlags | Flags,
FileInfoTimeout,
MaxFileNodes,
MaxFileSize,
VolumePrefix,
RootSddl,
&Memfs);
if (!NT_SUCCESS(Result))
{
fail(L"cannot create MEMFS");
goto exit;
}
FspFileSystemSetDebugLog(MemfsFileSystem(Memfs), DebugFlags);
if (0 != MountPoint && L'\0' != MountPoint[0])
{
Result = FspFileSystemSetMountPoint(MemfsFileSystem(Memfs),
L'*' == MountPoint[0] && L'\0' == MountPoint[1] ? 0 : MountPoint);
if (!NT_SUCCESS(Result))
{
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));
info(L"%s -t %ld -n %ld -s %ld%s%s%s%s%s%s",
L"" PROGNAME, FileInfoTimeout, MaxFileNodes, MaxFileSize,
RootSddl ? L" -S " : L"", RootSddl ? RootSddl : L"",
0 != VolumePrefix && L'\0' != VolumePrefix[0] ? L" -u " : L"",
0 != VolumePrefix && L'\0' != VolumePrefix[0] ? VolumePrefix : L"",
MountPoint ? L" -m " : L"", MountPoint ? MountPoint : L"");
Service->UserContext = Memfs;
Result = STATUS_SUCCESS;
exit:
if (!NT_SUCCESS(Result) && 0 != Memfs)
MemfsDelete(Memfs);
return Result;
usage:
static wchar_t usage[] = L""
"usage: %s OPTIONS\n"
"\n"
"options:\n"
" -d DebugFlags [-1: enable all debug logs]\n"
" -D DebugLogFile [file path; use - for stdout]\n"
" -i [case insensitive file system]\n"
" -t FileInfoTimeout [millis]\n"
" -n MaxFileNodes\n"
" -s MaxFileSize [bytes]\n"
" -S RootSddl [file rights: FA, etc; NO generic rights: GA, etc.]\n"
" -u \\Server\\Share [UNC prefix (single backslash)]\n"
" -m MountPoint [X:|* (required if no UNC prefix)]\n";
fail(usage, L"" PROGNAME);
return STATUS_UNSUCCESSFUL;
}
NTSTATUS SvcStop(FSP_SERVICE *Service)
{
MEMFS *Memfs = Service->UserContext;
MemfsStop(Memfs);
MemfsDelete(Memfs);
return STATUS_SUCCESS;
}
int wmain(int argc, wchar_t **argv)
{
return FspServiceRun(L"" PROGNAME, SvcStart, SvcStop, 0);
}