mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -05:00
Merge pull request #181 from JohnOberschelp/master
Added DeviceIoControl to Airfs
This commit is contained in:
commit
999847d8db
@ -38,9 +38,13 @@ FSP_FSCTL_STATIC_ASSERT(AIRFS_MAX_PATH > MAX_PATH,
|
|||||||
#define AIRFS_NAMED_STREAMS // Include alternate data streams support.
|
#define AIRFS_NAMED_STREAMS // Include alternate data streams support.
|
||||||
#define AIRFS_DIRINFO_BY_NAME // Include GetDirInfoByName.
|
#define AIRFS_DIRINFO_BY_NAME // Include GetDirInfoByName.
|
||||||
#define AIRFS_SLOWIO // Include delayed I/O response support.
|
#define AIRFS_SLOWIO // Include delayed I/O response support.
|
||||||
|
#define AIRFS_CONTROL // Include DeviceIoControl support.
|
||||||
|
|
||||||
#define AIRFS_SECTOR_SIZE 512
|
|
||||||
#define AIRFS_SECTORS_PER_ALLOCATION_UNIT 1
|
#define SECTOR_SIZE 512
|
||||||
|
#define SECTORS_PER_ALLOCATION_UNIT 1
|
||||||
|
#define ALLOCATION_UNIT ( SECTOR_SIZE * SECTORS_PER_ALLOCATION_UNIT )
|
||||||
|
#define IN_ALLOCATION_UNITS(bytes) (((bytes) + ALLOCATION_UNIT - 1) / ALLOCATION_UNIT * ALLOCATION_UNIT)
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -660,10 +664,11 @@ NTSTATUS SetAllocSize(FSP_FILE_SYSTEM *FileSystem, NODE_ Node,
|
|||||||
{
|
{
|
||||||
AIRFS_ Airfs = (AIRFS_) FileSystem->UserContext;
|
AIRFS_ Airfs = (AIRFS_) FileSystem->UserContext;
|
||||||
|
|
||||||
|
RequestedAllocSize = IN_ALLOCATION_UNITS(RequestedAllocSize);
|
||||||
|
|
||||||
if (Node->FileInfo.AllocationSize != RequestedAllocSize)
|
if (Node->FileInfo.AllocationSize != RequestedAllocSize)
|
||||||
{
|
{
|
||||||
if (RequestedAllocSize > Airfs->MaxFileSize)
|
if (RequestedAllocSize > Airfs->MaxFileSize) return STATUS_DISK_FULL;
|
||||||
return STATUS_DISK_FULL;
|
|
||||||
|
|
||||||
// Reallocate only if the file is made smaller, or if it will not fit in the actual memory footprint.
|
// Reallocate only if the file is made smaller, or if it will not fit in the actual memory footprint.
|
||||||
size_t ActualSize = AirfsHeapSize(Node->FileData);
|
size_t ActualSize = AirfsHeapSize(Node->FileData);
|
||||||
@ -671,7 +676,7 @@ NTSTATUS SetAllocSize(FSP_FILE_SYSTEM *FileSystem, NODE_ Node,
|
|||||||
{
|
{
|
||||||
// If the file grow request was modest, guess that it might happen again, and grow the file by 50%.
|
// If the file grow request was modest, guess that it might happen again, and grow the file by 50%.
|
||||||
if (RequestedAllocSize > Node->FileInfo.AllocationSize && RequestedAllocSize <= ActualSize + ActualSize / 8)
|
if (RequestedAllocSize > Node->FileInfo.AllocationSize && RequestedAllocSize <= ActualSize + ActualSize / 8)
|
||||||
RequestedAllocSize = (ActualSize + ActualSize / 2 + 7) ^ 7;
|
RequestedAllocSize = IN_ALLOCATION_UNITS(ActualSize + ActualSize / 2);
|
||||||
|
|
||||||
PVOID FileData = AirfsHeapRealloc(Node->FileData, (size_t)RequestedAllocSize);
|
PVOID FileData = AirfsHeapRealloc(Node->FileData, (size_t)RequestedAllocSize);
|
||||||
if (!FileData && RequestedAllocSize > 0)
|
if (!FileData && RequestedAllocSize > 0)
|
||||||
@ -697,10 +702,7 @@ NTSTATUS SetFileSize(FSP_FILE_SYSTEM *FileSystem, NODE_ Node,
|
|||||||
{
|
{
|
||||||
if (Node->FileInfo.AllocationSize < RequestedFileSize)
|
if (Node->FileInfo.AllocationSize < RequestedFileSize)
|
||||||
{
|
{
|
||||||
UINT64 AllocationUnit = AIRFS_SECTOR_SIZE * AIRFS_SECTORS_PER_ALLOCATION_UNIT;
|
NTSTATUS Result = SetAllocSize(FileSystem, Node, RequestedFileSize);
|
||||||
UINT64 AllocationSize = (RequestedFileSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit;
|
|
||||||
|
|
||||||
NTSTATUS Result = SetAllocSize(FileSystem, Node, AllocationSize);
|
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@ -1054,11 +1056,7 @@ void ApiCleanup(FSP_FILE_SYSTEM *FileSystem, PVOID Node0, PWSTR Name, ULONG Flag
|
|||||||
|
|
||||||
if (Flags & FspCleanupSetAllocationSize)
|
if (Flags & FspCleanupSetAllocationSize)
|
||||||
{
|
{
|
||||||
UINT64 AllocationUnit = AIRFS_SECTOR_SIZE * AIRFS_SECTORS_PER_ALLOCATION_UNIT;
|
SetAllocSize(FileSystem, Node, Node->FileInfo.FileSize);
|
||||||
UINT64 AllocationSize = (Node->FileInfo.FileSize + AllocationUnit - 1) /
|
|
||||||
AllocationUnit * AllocationUnit;
|
|
||||||
|
|
||||||
SetAllocSize(FileSystem, Node, AllocationSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Flags & FspCleanupDelete) && !NodeHasChildren(Node))
|
if ((Flags & FspCleanupDelete) && !NodeHasChildren(Node))
|
||||||
@ -1609,6 +1607,34 @@ NTSTATUS ApiGetStreamInfo(FSP_FILE_SYSTEM *FileSystem, PVOID Node0,
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
#if defined(AIRFS_CONTROL)
|
||||||
|
|
||||||
|
NTSTATUS ApiControl(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
PVOID FileContext, UINT32 ControlCode,
|
||||||
|
PVOID InputBuffer, ULONG InputBufferLength,
|
||||||
|
PVOID OutputBuffer, ULONG OutputBufferLength, PULONG PBytesTransferred)
|
||||||
|
{
|
||||||
|
// Trivial example: Perform a ROT13 translation on alphas.
|
||||||
|
if (CTL_CODE(0x8000 + 'M', 'R', METHOD_BUFFERED, FILE_ANY_ACCESS) == ControlCode)
|
||||||
|
{
|
||||||
|
if (OutputBufferLength != InputBufferLength) return STATUS_INVALID_PARAMETER;
|
||||||
|
for (ULONG i = 0; i < InputBufferLength; i++)
|
||||||
|
{
|
||||||
|
char c = ((char*)InputBuffer)[i];
|
||||||
|
if (('A' <= c && c <= 'M') || ('a' <= c && c <= 'm')) c += 13;
|
||||||
|
else
|
||||||
|
if (('N' <= c && c <= 'Z') || ('n' <= c && c <= 'z')) c -= 13;
|
||||||
|
((char*)OutputBuffer)[i] = c;
|
||||||
|
}
|
||||||
|
*PBytesTransferred = InputBufferLength;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -1654,6 +1680,11 @@ FSP_FILE_SYSTEM_INTERFACE AirfsInterface =
|
|||||||
#else
|
#else
|
||||||
0,
|
0,
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(AIRFS_CONTROL)
|
||||||
|
ApiControl,
|
||||||
|
#else
|
||||||
|
0,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -1711,7 +1742,6 @@ NTSTATUS AirfsCreate(
|
|||||||
BOOLEAN FlushAndPurgeOnCleanup = !!(Flags & AirfsFlushAndPurgeOnCleanup);
|
BOOLEAN FlushAndPurgeOnCleanup = !!(Flags & AirfsFlushAndPurgeOnCleanup);
|
||||||
PWSTR DevicePath = AirfsNet == (Flags & AirfsDeviceMask) ?
|
PWSTR DevicePath = AirfsNet == (Flags & AirfsDeviceMask) ?
|
||||||
L"" FSP_FSCTL_NET_DEVICE_NAME : L"" FSP_FSCTL_DISK_DEVICE_NAME;
|
L"" FSP_FSCTL_NET_DEVICE_NAME : L"" FSP_FSCTL_DISK_DEVICE_NAME;
|
||||||
UINT64 AllocationUnit;
|
|
||||||
AIRFS_ Airfs;
|
AIRFS_ Airfs;
|
||||||
NODE_ RootNode;
|
NODE_ RootNode;
|
||||||
PSECURITY_DESCRIPTOR RootSecurity;
|
PSECURITY_DESCRIPTOR RootSecurity;
|
||||||
@ -1737,8 +1767,7 @@ NTSTATUS AirfsCreate(
|
|||||||
|
|
||||||
memset(Airfs, 0, sizeof *Airfs);
|
memset(Airfs, 0, sizeof *Airfs);
|
||||||
Airfs->MaxNodes = MaxNodes;
|
Airfs->MaxNodes = MaxNodes;
|
||||||
AllocationUnit = AIRFS_SECTOR_SIZE * AIRFS_SECTORS_PER_ALLOCATION_UNIT;
|
Airfs->MaxFileSize = IN_ALLOCATION_UNITS(MaxFileSize);
|
||||||
Airfs->MaxFileSize = (ULONG)((MaxFileSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit);
|
|
||||||
|
|
||||||
#ifdef AIRFS_SLOWIO
|
#ifdef AIRFS_SLOWIO
|
||||||
Airfs->SlowioMaxDelay = SlowioMaxDelay;
|
Airfs->SlowioMaxDelay = SlowioMaxDelay;
|
||||||
@ -1750,8 +1779,8 @@ NTSTATUS AirfsCreate(
|
|||||||
|
|
||||||
memset(&VolumeParams, 0, sizeof VolumeParams);
|
memset(&VolumeParams, 0, sizeof VolumeParams);
|
||||||
VolumeParams.Version = sizeof FSP_FSCTL_VOLUME_PARAMS;
|
VolumeParams.Version = sizeof FSP_FSCTL_VOLUME_PARAMS;
|
||||||
VolumeParams.SectorSize = AIRFS_SECTOR_SIZE;
|
VolumeParams.SectorSize = SECTOR_SIZE;
|
||||||
VolumeParams.SectorsPerAllocationUnit = AIRFS_SECTORS_PER_ALLOCATION_UNIT;
|
VolumeParams.SectorsPerAllocationUnit = SECTORS_PER_ALLOCATION_UNIT;
|
||||||
VolumeParams.VolumeCreationTime = GetSystemTime();
|
VolumeParams.VolumeCreationTime = GetSystemTime();
|
||||||
VolumeParams.VolumeSerialNumber = (UINT32)(GetSystemTime() / (10000 * 1000));
|
VolumeParams.VolumeSerialNumber = (UINT32)(GetSystemTime() / (10000 * 1000));
|
||||||
VolumeParams.FileInfoTimeout = FileInfoTimeout;
|
VolumeParams.FileInfoTimeout = FileInfoTimeout;
|
||||||
@ -1769,6 +1798,9 @@ NTSTATUS AirfsCreate(
|
|||||||
VolumeParams.PassQueryDirectoryFileName = 1;
|
VolumeParams.PassQueryDirectoryFileName = 1;
|
||||||
#endif
|
#endif
|
||||||
VolumeParams.FlushAndPurgeOnCleanup = FlushAndPurgeOnCleanup;
|
VolumeParams.FlushAndPurgeOnCleanup = FlushAndPurgeOnCleanup;
|
||||||
|
#if defined(AIRFS_CONTROL)
|
||||||
|
VolumeParams.DeviceControl = 1;
|
||||||
|
#endif
|
||||||
if (VolumePrefix)
|
if (VolumePrefix)
|
||||||
wcscpy_s(VolumeParams.Prefix, sizeof VolumeParams.Prefix / sizeof(WCHAR), VolumePrefix);
|
wcscpy_s(VolumeParams.Prefix, sizeof VolumeParams.Prefix / sizeof(WCHAR), VolumePrefix);
|
||||||
wcscpy_s(VolumeParams.FileSystemName, sizeof VolumeParams.FileSystemName / sizeof(WCHAR),
|
wcscpy_s(VolumeParams.FileSystemName, sizeof VolumeParams.FileSystemName / sizeof(WCHAR),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user