mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 17:03:12 -05:00
sys: fsctl
This commit is contained in:
parent
e60e63ada0
commit
cac74f3b63
@ -149,7 +149,6 @@
|
|||||||
<ClCompile Include="..\..\src\sys\resource.c" />
|
<ClCompile Include="..\..\src\sys\resource.c" />
|
||||||
<ClCompile Include="..\..\src\sys\security.c" />
|
<ClCompile Include="..\..\src\sys\security.c" />
|
||||||
<ClCompile Include="..\..\src\sys\shutdown.c" />
|
<ClCompile Include="..\..\src\sys\shutdown.c" />
|
||||||
<ClCompile Include="..\..\src\sys\transact.c" />
|
|
||||||
<ClCompile Include="..\..\src\sys\volinfo.c" />
|
<ClCompile Include="..\..\src\sys\volinfo.c" />
|
||||||
<ClCompile Include="..\..\src\sys\write.c" />
|
<ClCompile Include="..\..\src\sys\write.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -77,9 +77,6 @@
|
|||||||
<ClCompile Include="..\..\src\sys\ioq.c">
|
<ClCompile Include="..\..\src\sys\ioq.c">
|
||||||
<Filter>Source</Filter>
|
<Filter>Source</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\sys\transact.c">
|
|
||||||
<Filter>Source</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\src\sys\driver.h">
|
<ClInclude Include="..\..\src\sys\driver.h">
|
||||||
|
@ -31,6 +31,7 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid =
|
|||||||
|
|
||||||
#define FSP_FSCTL_CREATE_BUFFER_SIZE 64
|
#define FSP_FSCTL_CREATE_BUFFER_SIZE 64
|
||||||
#define FSP_FSCTL_TRANSACT_BUFFER_SIZE 4096
|
#define FSP_FSCTL_TRANSACT_BUFFER_SIZE 4096
|
||||||
|
#define FSP_FSCTL_TRANSACT_REQ_SIZEMAX 1536
|
||||||
|
|
||||||
/* marshalling */
|
/* marshalling */
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
@ -162,25 +162,14 @@ typedef struct
|
|||||||
IO_CSQ PendingIoCsq, ProcessIoCsq;
|
IO_CSQ PendingIoCsq, ProcessIoCsq;
|
||||||
} FSP_IOQ;
|
} FSP_IOQ;
|
||||||
VOID FspIoqInitialize(FSP_IOQ *Ioq);
|
VOID FspIoqInitialize(FSP_IOQ *Ioq);
|
||||||
VOID FspIoqEnable(FSP_IOQ *Ioq, int Delta);
|
BOOLEAN FspIoqEnabled(FSP_IOQ *Ioq);
|
||||||
PKEVENT FspIoqPendingIrpEvent(FSP_IOQ *Ioq);
|
VOID FspIoqDisable(FSP_IOQ *Ioq);
|
||||||
BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp);
|
BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp);
|
||||||
PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, ULONG millis);
|
PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, ULONG millis);
|
||||||
BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp);
|
BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp);
|
||||||
PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint);
|
PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint);
|
||||||
VOID FspIoqCancelAll(FSP_IOQ *Ioq);
|
VOID FspIoqCancelAll(FSP_IOQ *Ioq);
|
||||||
|
|
||||||
/* transact thread */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
PKTHREAD Thread;
|
|
||||||
KEVENT Event;
|
|
||||||
FSP_IOQ *TransactIoq, *Ioq;
|
|
||||||
} FSP_TRANSACT_THREAD;
|
|
||||||
NTSTATUS FspTransactThreadStart(FSP_TRANSACT_THREAD *TransactThread,
|
|
||||||
FSP_IOQ *TransactIoq, FSP_IOQ *Ioq);
|
|
||||||
VOID FspTransactThreadStop(FSP_TRANSACT_THREAD *TransactThread);
|
|
||||||
|
|
||||||
/* device extensions */
|
/* device extensions */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -199,8 +188,7 @@ typedef struct
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
FSP_DEVICE_EXTENSION Base;
|
FSP_DEVICE_EXTENSION Base;
|
||||||
FSP_IOQ TransactIoq, Ioq;
|
FSP_IOQ Ioq;
|
||||||
FSP_TRANSACT_THREAD TransactThread;
|
|
||||||
UINT8 SecurityDescriptorBuf[];
|
UINT8 SecurityDescriptorBuf[];
|
||||||
} FSP_FSVRT_DEVICE_EXTENSION;
|
} FSP_FSVRT_DEVICE_EXTENSION;
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -79,15 +79,10 @@ static NTSTATUS FspFsctlCreateVolume(
|
|||||||
{
|
{
|
||||||
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject);
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject);
|
||||||
FsvrtDeviceExtension->Base.Kind = FspFsvrtDeviceExtensionKind;
|
FsvrtDeviceExtension->Base.Kind = FspFsvrtDeviceExtensionKind;
|
||||||
FspIoqInitialize(&FsvrtDeviceExtension->TransactIoq);
|
|
||||||
FspIoqInitialize(&FsvrtDeviceExtension->Ioq);
|
FspIoqInitialize(&FsvrtDeviceExtension->Ioq);
|
||||||
RtlCopyMemory(FspFsvrtDeviceExtension(FsvrtDeviceObject)->SecurityDescriptorBuf,
|
RtlCopyMemory(FspFsvrtDeviceExtension(FsvrtDeviceObject)->SecurityDescriptorBuf,
|
||||||
SecurityDescriptor, InputBufferLength);
|
SecurityDescriptor, InputBufferLength);
|
||||||
Irp->IoStatus.Information = DeviceName.Length + 1;
|
Irp->IoStatus.Information = DeviceName.Length + 1;
|
||||||
Result = FspTransactThreadStart(&FsvrtDeviceExtension->TransactThread,
|
|
||||||
&FsvrtDeviceExtension->TransactIoq, &FsvrtDeviceExtension->Ioq);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
IoDeleteDevice(FsvrtDeviceObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free the temporary security descriptor */
|
/* free the temporary security descriptor */
|
||||||
@ -125,9 +120,10 @@ static NTSTATUS FspFsvrtTransact(
|
|||||||
|
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject);
|
FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(DeviceObject);
|
||||||
PUINT8 SystemBufferEnd;
|
PUINT8 SystemBufferPtr, SystemBufferEnd;
|
||||||
FSP_TRANSACT_RSP *Response;
|
FSP_TRANSACT_RSP *Response;
|
||||||
PIRP ProcessIrp;
|
FSP_TRANSACT_REQ *Request;
|
||||||
|
PIRP ProcessIrp, PendingIrp;
|
||||||
|
|
||||||
/* access check */
|
/* access check */
|
||||||
Result = FspSecuritySubjectContextAccessCheck(
|
Result = FspSecuritySubjectContextAccessCheck(
|
||||||
@ -155,12 +151,43 @@ static NTSTATUS FspFsvrtTransact(
|
|||||||
Response = (PVOID)((PUINT8)Response + Response->Size);
|
Response = (PVOID)((PUINT8)Response + Response->Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FspIoqPostIrp(&FsvrtDeviceExtension->TransactIoq, Irp))
|
/* wait for a pending IRP */
|
||||||
Result = STATUS_PENDING;
|
while (0 == (PendingIrp = FspIoqNextPendingIrp(&FsvrtDeviceExtension->Ioq, 300)))
|
||||||
else
|
{
|
||||||
Result = STATUS_ACCESS_DENIED;
|
if (!FspIoqEnabled(&FsvrtDeviceExtension->Ioq))
|
||||||
|
return STATUS_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
return Result;
|
/* send any pending IRP's to the user-mode file system */
|
||||||
|
SystemBufferPtr = SystemBuffer;
|
||||||
|
SystemBufferEnd = (PUINT8)SystemBuffer + OutputBufferLength;
|
||||||
|
ASSERT(SystemBufferPtr + FSP_FSCTL_TRANSACT_REQ_SIZEMAX + sizeof(Request->Size) <= SystemBufferEnd);
|
||||||
|
for (BOOLEAN LoopedOnce = FALSE;; LoopedOnce = TRUE)
|
||||||
|
{
|
||||||
|
if (SystemBufferPtr + FSP_FSCTL_TRANSACT_REQ_SIZEMAX + sizeof(Request->Size) > SystemBufferEnd)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!FspIoqStartProcessingIrp(&FsvrtDeviceExtension->Ioq, PendingIrp))
|
||||||
|
{
|
||||||
|
FspCompleteRequest(PendingIrp, STATUS_CANCELLED);
|
||||||
|
if (!LoopedOnce)
|
||||||
|
return STATUS_CANCELLED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Request = PendingIrp->Tail.Overlay.DriverContext[0];
|
||||||
|
RtlCopyMemory(SystemBufferPtr, Request, Request->Size);
|
||||||
|
SystemBufferPtr += Request->Size;
|
||||||
|
|
||||||
|
PendingIrp = FspIoqNextPendingIrp(&FsvrtDeviceExtension->Ioq, 0);
|
||||||
|
if (0 == PendingIrp)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ASSERT(SystemBufferPtr + sizeof(Request->Size) <= SystemBufferEnd);
|
||||||
|
RtlZeroMemory(SystemBufferPtr, SystemBufferEnd - SystemBufferPtr);
|
||||||
|
Irp->IoStatus.Information = SystemBufferPtr - (PUINT8)SystemBuffer;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFsctlFileSystemControl(
|
static NTSTATUS FspFsctlFileSystemControl(
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
static NTSTATUS FspIoqPendingInsertIrpEx(PIO_CSQ IoCsq, PIRP Irp, PVOID InsertContext)
|
static NTSTATUS FspIoqPendingInsertIrpEx(PIO_CSQ IoCsq, PIRP Irp, PVOID InsertContext)
|
||||||
{
|
{
|
||||||
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, PendingIoCsq);
|
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, PendingIoCsq);
|
||||||
if (0 > Ioq->Enabled)
|
if (0 >= Ioq->Enabled)
|
||||||
return STATUS_ACCESS_DENIED;
|
return STATUS_ACCESS_DENIED;
|
||||||
InsertTailList(&Ioq->PendingIrpList, &Irp->Tail.Overlay.ListEntry);
|
InsertTailList(&Ioq->PendingIrpList, &Irp->Tail.Overlay.ListEntry);
|
||||||
/* list is not empty; wake up any waiters */
|
/* list is not empty; wake up any waiters */
|
||||||
@ -101,7 +101,7 @@ static VOID FspIoqPendingCompleteCanceledIrp(PIO_CSQ IoCsq, PIRP Irp)
|
|||||||
static NTSTATUS FspIoqProcessInsertIrpEx(PIO_CSQ IoCsq, PIRP Irp, PVOID InsertContext)
|
static NTSTATUS FspIoqProcessInsertIrpEx(PIO_CSQ IoCsq, PIRP Irp, PVOID InsertContext)
|
||||||
{
|
{
|
||||||
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, ProcessIoCsq);
|
FSP_IOQ *Ioq = CONTAINING_RECORD(IoCsq, FSP_IOQ, ProcessIoCsq);
|
||||||
if (0 > Ioq->Enabled)
|
if (0 >= Ioq->Enabled)
|
||||||
return STATUS_ACCESS_DENIED;
|
return STATUS_ACCESS_DENIED;
|
||||||
InsertTailList(&Ioq->ProcessIrpList, &Irp->Tail.Overlay.ListEntry);
|
InsertTailList(&Ioq->ProcessIrpList, &Irp->Tail.Overlay.ListEntry);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
@ -164,21 +164,27 @@ VOID FspIoqInitialize(FSP_IOQ *Ioq)
|
|||||||
FspIoqProcessAcquireLock,
|
FspIoqProcessAcquireLock,
|
||||||
FspIoqProcessReleaseLock,
|
FspIoqProcessReleaseLock,
|
||||||
FspIoqProcessCompleteCanceledIrp);
|
FspIoqProcessCompleteCanceledIrp);
|
||||||
|
Ioq->Enabled = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FspIoqEnable(FSP_IOQ *Ioq, int Delta)
|
BOOLEAN FspIoqEnabled(FSP_IOQ *Ioq)
|
||||||
|
{
|
||||||
|
BOOLEAN Result;
|
||||||
|
KIRQL Irql;
|
||||||
|
KeAcquireSpinLock(&Ioq->SpinLock, &Irql);
|
||||||
|
Result = 0 < Ioq->Enabled;
|
||||||
|
KeReleaseSpinLock(&Ioq->SpinLock, Irql);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FspIoqDisable(FSP_IOQ *Ioq)
|
||||||
{
|
{
|
||||||
KIRQL Irql;
|
KIRQL Irql;
|
||||||
KeAcquireSpinLock(&Ioq->SpinLock, &Irql);
|
KeAcquireSpinLock(&Ioq->SpinLock, &Irql);
|
||||||
Ioq->Enabled += Delta;
|
Ioq->Enabled = 0;
|
||||||
KeReleaseSpinLock(&Ioq->SpinLock, Irql);
|
KeReleaseSpinLock(&Ioq->SpinLock, Irql);
|
||||||
}
|
}
|
||||||
|
|
||||||
PKEVENT FspIoqPendingIrpEvent(FSP_IOQ *Ioq)
|
|
||||||
{
|
|
||||||
return &Ioq->PendingIrpEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp)
|
BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file sys/transact.c
|
|
||||||
*
|
|
||||||
* @copyright 2015 Bill Zissimopoulos
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/driver.h>
|
|
||||||
|
|
||||||
static KSTART_ROUTINE FspTransactThread;
|
|
||||||
NTSTATUS FspTransactThreadStart(FSP_TRANSACT_THREAD *TransactThread,
|
|
||||||
FSP_IOQ *TransactIoq, FSP_IOQ *Ioq);
|
|
||||||
VOID FspTransactThreadStop(FSP_TRANSACT_THREAD *TransactThread);
|
|
||||||
|
|
||||||
#ifdef ALLOC_PRAGMA
|
|
||||||
#pragma alloc_text(PAGE, FspTransactThread)
|
|
||||||
#pragma alloc_text(PAGE, FspTransactThreadStart)
|
|
||||||
#pragma alloc_text(PAGE, FspTransactThreadStop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static VOID FspTransactThread(PVOID StartContext)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
FSP_TRANSACT_THREAD *TransactThread = StartContext;
|
|
||||||
PVOID WaitObjects[2];
|
|
||||||
WaitObjects[0] = &TransactThread->Event;
|
|
||||||
WaitObjects[1] = FspIoqPendingIrpEvent(TransactThread->TransactIoq);
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
NTSTATUS Result;
|
|
||||||
PIRP Irp;
|
|
||||||
|
|
||||||
Result = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, Executive, KernelMode, FALSE, 0, 0);
|
|
||||||
if (STATUS_WAIT_0 == Result)
|
|
||||||
break; /* stop thread */
|
|
||||||
else if (STATUS_WAIT_1 != Result)
|
|
||||||
continue; /* retry */
|
|
||||||
|
|
||||||
Irp = FspIoqNextPendingIrp(TransactThread->TransactIoq, 0);
|
|
||||||
if (0 == Irp)
|
|
||||||
continue; /* retry */
|
|
||||||
}
|
|
||||||
|
|
||||||
PsTerminateSystemThread(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS FspTransactThreadStart(FSP_TRANSACT_THREAD *TransactThread,
|
|
||||||
FSP_IOQ *TransactIoq, FSP_IOQ *Ioq)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
NTSTATUS Result;
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
HANDLE ThreadHandle;
|
|
||||||
|
|
||||||
RtlZeroMemory(TransactThread, sizeof *TransactThread);
|
|
||||||
KeInitializeEvent(&TransactThread->Event, NotificationEvent, FALSE);
|
|
||||||
TransactThread->TransactIoq = TransactIoq;
|
|
||||||
TransactThread->Ioq = Ioq;
|
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes, 0, OBJ_KERNEL_HANDLE, 0, 0);
|
|
||||||
Result = PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, &ObjectAttributes, 0, 0,
|
|
||||||
FspTransactThread, TransactThread);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
return Result;
|
|
||||||
|
|
||||||
Result = ObReferenceObjectByHandle(ThreadHandle, THREAD_ALL_ACCESS, *PsThreadType, KernelMode,
|
|
||||||
&TransactThread->Thread, 0);
|
|
||||||
ASSERT(NT_SUCCESS(Result));
|
|
||||||
|
|
||||||
ZwClose(ThreadHandle);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID FspTransactThreadStop(FSP_TRANSACT_THREAD *TransactThread)
|
|
||||||
{
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
KeSetEvent(&TransactThread->Event, 1, TRUE);
|
|
||||||
KeWaitForSingleObject(&TransactThread->Thread, Executive, KernelMode, FALSE, 0);
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user