sys,dll: DeviceControl operation

This commit is contained in:
Bill Zissimopoulos
2018-05-04 13:56:20 -07:00
parent 7aadf259d9
commit 894ae7b8f3
10 changed files with 296 additions and 5 deletions

View File

@ -55,6 +55,11 @@ FSP_FSCTL_STATIC_ASSERT(MEMFS_MAX_PATH > MAX_PATH,
*/
#define MEMFS_SLOWIO
/*
* Define the MEMFS_CONTROL macro to include DeviceControl support.
*/
#define MEMFS_CONTROL
/*
* Define the DEBUG_BUFFER_CHECK macro on Windows 8 or above. This includes
* a check for the Write buffer to ensure that it is read-only.
@ -1895,6 +1900,38 @@ static NTSTATUS GetStreamInfo(FSP_FILE_SYSTEM *FileSystem,
}
#endif
#if defined(MEMFS_CONTROL)
static NTSTATUS Control(FSP_FILE_SYSTEM *FileSystem,
PVOID FileContext, UINT32 ControlCode,
PVOID InputBuffer, ULONG InputBufferLength,
PVOID OutputBuffer, ULONG OutputBufferLength, PULONG PBytesTransferred)
{
/* MEMFS also supports encryption! See below :) */
if (CTL_CODE(0x8000 + 'M', 'R', METHOD_BUFFERED, FILE_ANY_ACCESS) == ControlCode)
{
if (OutputBufferLength != InputBufferLength)
return STATUS_INVALID_PARAMETER;
for (PUINT8 P = (PUINT8)InputBuffer, Q = (PUINT8)OutputBuffer, EndP = P + InputBufferLength;
EndP > P; P++, Q++)
{
if (('A' <= *P && *P <= 'M') || ('a' <= *P && *P <= 'm'))
*Q = *P + 13;
else
if (('N' <= *P && *P <= 'Z') || ('n' <= *P && *P <= 'z'))
*Q = *P - 13;
else
*Q = *P;
}
*PBytesTransferred = InputBufferLength;
return STATUS_SUCCESS;
}
return STATUS_INVALID_DEVICE_REQUEST;
}
#endif
static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
{
GetVolumeInfo,
@ -1937,6 +1974,11 @@ static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
#else
0,
#endif
#if defined(MEMFS_CONTROL)
Control,
#else
0,
#endif
};
/*
@ -2028,6 +2070,9 @@ NTSTATUS MemfsCreateFunnel(
VolumeParams.PassQueryDirectoryFileName = 1;
#endif
VolumeParams.FlushAndPurgeOnCleanup = FlushAndPurgeOnCleanup;
#if defined(MEMFS_CONTROL)
VolumeParams.DeviceControl = 1;
#endif
if (0 != VolumePrefix)
wcscpy_s(VolumeParams.Prefix, sizeof VolumeParams.Prefix / sizeof(WCHAR), VolumePrefix);
wcscpy_s(VolumeParams.FileSystemName, sizeof VolumeParams.FileSystemName / sizeof(WCHAR),

View File

@ -0,0 +1,74 @@
/**
* @file devctl-test.c
*
* @copyright 2015-2018 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 <tlib/testsuite.h>
#include <strsafe.h>
#include "memfs.h"
#include "winfsp-tests.h"
static void devctl_dotest(ULONG Flags, PWSTR Prefix, PWSTR Drive)
{
void *memfs = memfs_start(Flags);
WCHAR FilePath[1024];
HANDLE Handle;
BOOL Success;
CHAR Buffer[26];
DWORD BytesTransferred;
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\",
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
Handle = CreateFileW(FilePath,
GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, 0);
ASSERT(INVALID_HANDLE_VALUE != Handle);
Success = DeviceIoControl(Handle,
CTL_CODE(0x8000 + 'M', 'R', METHOD_BUFFERED, FILE_ANY_ACCESS),
"ABCDEFghijklmNOPQRStuvwxyz", 26,
Buffer, sizeof Buffer,
&BytesTransferred,
0);
ASSERT(Success);
ASSERT(26 == BytesTransferred);
ASSERT(0 == memcmp("NOPQRStuvwxyzABCDEFghijklm", Buffer, BytesTransferred));
Success = CloseHandle(Handle);
ASSERT(Success);
memfs_stop(memfs);
}
static void devctl_test(void)
{
if (WinFspDiskTests)
devctl_dotest(MemfsDisk, 0, 0);
if (WinFspNetTests)
devctl_dotest(MemfsNet, L"\\\\memfs\\share", L"\\\\memfs\\share");
}
void devctl_tests(void)
{
if (OptExternal)
return;
TEST(devctl_test);
}

View File

@ -199,6 +199,7 @@ int main(int argc, char *argv[])
TESTSUITE(lock_tests);
TESTSUITE(dirctl_tests);
TESTSUITE(exec_tests);
TESTSUITE(devctl_tests);
TESTSUITE(reparse_tests);
TESTSUITE(stream_tests);
TESTSUITE(oplock_tests);