sys: FspTransactThread

This commit is contained in:
Bill Zissimopoulos 2015-11-24 15:59:43 -08:00
parent be204b4118
commit 25f6bd52a7
5 changed files with 104 additions and 1 deletions

View File

@ -149,6 +149,7 @@
<ClCompile Include="..\..\src\sys\resource.c" />
<ClCompile Include="..\..\src\sys\security.c" />
<ClCompile Include="..\..\src\sys\shutdown.c" />
<ClCompile Include="..\..\src\sys\transact.c" />
<ClCompile Include="..\..\src\sys\volinfo.c" />
<ClCompile Include="..\..\src\sys\write.c" />
</ItemGroup>

View File

@ -77,6 +77,9 @@
<ClCompile Include="..\..\src\sys\ioq.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\..\src\sys\transact.c">
<Filter>Source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\sys\driver.h">

View File

@ -155,12 +155,24 @@ typedef struct
} FSP_IOQ;
VOID FspIoqInitialize(FSP_IOQ *Ioq);
VOID FspIoqEnable(FSP_IOQ *Ioq, int Delta);
PKEVENT FspIoqPendingIrpEvent(FSP_IOQ *Ioq);
BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp);
PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, ULONG millis);
BOOLEAN FspIoqStartProcessingIrp(FSP_IOQ *Ioq, PIRP Irp);
PIRP FspIoqEndProcessingIrp(FSP_IOQ *Ioq, UINT_PTR IrpHint);
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 */
enum
{

View File

@ -174,6 +174,11 @@ VOID FspIoqEnable(FSP_IOQ *Ioq, int Delta)
KeReleaseSpinLock(&Ioq->SpinLock, Irql);
}
PKEVENT FspIoqPendingIrpEvent(FSP_IOQ *Ioq)
{
return &Ioq->PendingIrpEvent;
}
BOOLEAN FspIoqPostIrp(FSP_IOQ *Ioq, PIRP Irp)
{
NTSTATUS Result;
@ -190,7 +195,7 @@ PIRP FspIoqNextPendingIrp(FSP_IOQ *Ioq, ULONG millis)
Timeout.QuadPart = (LONGLONG)millis * 10000;
Result = KeWaitForSingleObject(&Ioq->PendingIrpEvent, Executive, KernelMode, FALSE,
-1 == millis ? 0 : &Timeout);
if (!NT_SUCCESS(Result))
if (STATUS_SUCCESS != Result)
return 0;
}
return IoCsqRemoveNextIrp(&Ioq->PendingIoCsq, (PVOID)1);

82
src/sys/transact.c Normal file
View File

@ -0,0 +1,82 @@
/**
* @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);
}