reactos/sdk/lib/drivers/ntoskrnl_vista/io.c
Adam Słaboń 8d1beca119
[NTOSKRNL_VISTA] IoQueueWorkItemEx: Pass new context for the queue (#6276)
Passing parameter-provided context results in missing WorkerRoutine and WorkItem when callback is executed.
2024-01-11 12:29:53 +01:00

149 lines
3.4 KiB
C

/*
* PROJECT: ReactOS Kernel - Vista+ APIs
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Io functions of Vista+
* COPYRIGHT: 2016 Pierre Schweitzer (pierre@reactos.org)
* 2020 Victor Perevertkin (victor.perevertkin@reactos.org)
*/
#include <ntdef.h>
#include <ntifs.h>
typedef struct _EX_WORKITEM_CONTEXT
{
PIO_WORKITEM WorkItem;
PIO_WORKITEM_ROUTINE_EX WorkItemRoutineEx;
PVOID Context;
} EX_WORKITEM_CONTEXT, *PEX_WORKITEM_CONTEXT;
#define TAG_IOWI 'IWOI'
NTKRNLVISTAAPI
NTSTATUS
NTAPI
IoGetIrpExtraCreateParameter(IN PIRP Irp,
OUT PECP_LIST *ExtraCreateParameter)
{
/* Check we have a create operation */
if (!BooleanFlagOn(Irp->Flags, IRP_CREATE_OPERATION))
{
return STATUS_INVALID_PARAMETER;
}
/* If so, return user buffer */
*ExtraCreateParameter = Irp->UserBuffer;
return STATUS_SUCCESS;
}
_Function_class_(IO_WORKITEM_ROUTINE)
static
VOID
NTAPI
IopWorkItemExCallback(
PDEVICE_OBJECT DeviceObject,
PVOID Ctx)
{
PEX_WORKITEM_CONTEXT context = Ctx;
context->WorkItemRoutineEx(DeviceObject, context->Context, context->WorkItem);
ExFreePoolWithTag(context, TAG_IOWI);
}
NTKRNLVISTAAPI
VOID
NTAPI
IoQueueWorkItemEx(
_Inout_ PIO_WORKITEM IoWorkItem,
_In_ PIO_WORKITEM_ROUTINE_EX WorkerRoutine,
_In_ WORK_QUEUE_TYPE QueueType,
_In_opt_ __drv_aliasesMem PVOID Context)
{
PEX_WORKITEM_CONTEXT newContext = ExAllocatePoolWithTag(NonPagedPoolMustSucceed, sizeof(*newContext), TAG_IOWI);
newContext->WorkItem = IoWorkItem;
newContext->WorkItemRoutineEx = WorkerRoutine;
newContext->Context = Context;
IoQueueWorkItem(IoWorkItem, IopWorkItemExCallback, QueueType, newContext);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTKRNLVISTAAPI
NTSTATUS
NTAPI
IoSetDevicePropertyData(
_In_ PDEVICE_OBJECT Pdo,
_In_ CONST DEVPROPKEY *PropertyKey,
_In_ LCID Lcid,
_In_ ULONG Flags,
_In_ DEVPROPTYPE Type,
_In_ ULONG Size,
_In_opt_ PVOID Data)
{
return STATUS_NOT_IMPLEMENTED;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTKRNLVISTAAPI
NTSTATUS
NTAPI
IoGetDevicePropertyData(
_In_ PDEVICE_OBJECT Pdo,
_In_ CONST DEVPROPKEY *PropertyKey,
_In_ LCID Lcid,
_Reserved_ ULONG Flags,
_In_ ULONG Size,
_Out_ PVOID Data,
_Out_ PULONG RequiredSize,
_Out_ PDEVPROPTYPE Type)
{
return STATUS_NOT_IMPLEMENTED;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTKRNLVISTAAPI
NTSTATUS
IoSetDeviceInterfacePropertyData(
_In_ PUNICODE_STRING SymbolicLinkName,
_In_ CONST DEVPROPKEY *PropertyKey,
_In_ LCID Lcid,
_In_ ULONG Flags,
_In_ DEVPROPTYPE Type,
_In_ ULONG Size,
_In_reads_bytes_opt_(Size) PVOID Data)
{
return STATUS_NOT_IMPLEMENTED;
}
NTKRNLVISTAAPI
IO_PRIORITY_HINT
NTAPI
IoGetIoPriorityHint(
_In_ PIRP Irp)
{
return IoPriorityNormal;
}
NTKRNLVISTAAPI
VOID
IoSetMasterIrpStatus(
_Inout_ PIRP MasterIrp,
_In_ NTSTATUS Status)
{
NTSTATUS MasterStatus = MasterIrp->IoStatus.Status;
if (Status == STATUS_FT_READ_FROM_COPY)
{
return;
}
if ((Status == STATUS_VERIFY_REQUIRED) ||
(MasterStatus == STATUS_SUCCESS && !NT_SUCCESS(Status)) ||
(!NT_SUCCESS(MasterStatus) && !NT_SUCCESS(Status) && Status > MasterStatus))
{
MasterIrp->IoStatus.Status = Status;
}
}