xref: /reactos/sdk/lib/drivers/ntoskrnl_vista/io.c (revision 3ca21762)
1 /*
2  * PROJECT:     ReactOS Kernel - Vista+ APIs
3  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:     Io functions of Vista+
5  * COPYRIGHT:   2016 Pierre Schweitzer (pierre@reactos.org)
6  *              2020 Victor Perevertkin (victor.perevertkin@reactos.org)
7  */
8 
9 #include <ntdef.h>
10 #include <ntifs.h>
11 
12 typedef struct _EX_WORKITEM_CONTEXT
13 {
14     PIO_WORKITEM WorkItem;
15     PIO_WORKITEM_ROUTINE_EX WorkItemRoutineEx;
16     PVOID Context;
17 } EX_WORKITEM_CONTEXT, *PEX_WORKITEM_CONTEXT;
18 
19 #define TAG_IOWI 'IWOI'
20 
21 NTKERNELAPI
22 NTSTATUS
23 NTAPI
24 IoGetIrpExtraCreateParameter(IN PIRP Irp,
25                              OUT PECP_LIST *ExtraCreateParameter)
26 {
27     /* Check we have a create operation */
28     if (!BooleanFlagOn(Irp->Flags, IRP_CREATE_OPERATION))
29     {
30         return STATUS_INVALID_PARAMETER;
31     }
32 
33     /* If so, return user buffer */
34     *ExtraCreateParameter = Irp->UserBuffer;
35     return STATUS_SUCCESS;
36 }
37 
38 _Function_class_(IO_WORKITEM_ROUTINE)
39 static
40 VOID
41 NTAPI
42 IopWorkItemExCallback(
43     PDEVICE_OBJECT DeviceObject,
44     PVOID Ctx)
45 {
46     PEX_WORKITEM_CONTEXT context = Ctx;
47 
48     context->WorkItemRoutineEx(DeviceObject, context->Context, context->WorkItem);
49     ExFreePoolWithTag(context, TAG_IOWI);
50 }
51 
52 NTKERNELAPI
53 VOID
54 NTAPI
55 IoQueueWorkItemEx(
56     _Inout_ PIO_WORKITEM IoWorkItem,
57     _In_ PIO_WORKITEM_ROUTINE_EX WorkerRoutine,
58     _In_ WORK_QUEUE_TYPE QueueType,
59     _In_opt_ __drv_aliasesMem PVOID Context)
60 {
61     PEX_WORKITEM_CONTEXT newContext = ExAllocatePoolWithTag(NonPagedPoolMustSucceed, sizeof(*newContext), TAG_IOWI);
62     newContext->WorkItem = IoWorkItem;
63     newContext->WorkItemRoutineEx = WorkerRoutine;
64     newContext->Context = Context;
65 
66     IoQueueWorkItem(IoWorkItem, IopWorkItemExCallback, QueueType, Context);
67 }
68 
69 _IRQL_requires_max_(PASSIVE_LEVEL)
70 _Must_inspect_result_
71 NTKERNELAPI
72 NTSTATUS
73 NTAPI
74 IoGetDevicePropertyData(
75     _In_ PDEVICE_OBJECT Pdo,
76     _In_ CONST DEVPROPKEY *PropertyKey,
77     _In_ LCID Lcid,
78     _Reserved_ ULONG Flags,
79     _In_ ULONG Size,
80     _Out_ PVOID Data,
81     _Out_ PULONG RequiredSize,
82     _Out_ PDEVPROPTYPE Type)
83 {
84     return STATUS_NOT_IMPLEMENTED;
85 }
86 
87 _IRQL_requires_max_(PASSIVE_LEVEL)
88 _Must_inspect_result_
89 NTKERNELAPI
90 NTSTATUS
91 IoSetDeviceInterfacePropertyData(
92     _In_ PUNICODE_STRING SymbolicLinkName,
93     _In_ CONST DEVPROPKEY *PropertyKey,
94     _In_ LCID Lcid,
95     _In_ ULONG Flags,
96     _In_ DEVPROPTYPE Type,
97     _In_ ULONG Size,
98     _In_reads_bytes_opt_(Size) PVOID Data)
99 {
100     return STATUS_NOT_IMPLEMENTED;
101 }
102 
103 NTKERNELAPI
104 IO_PRIORITY_HINT
105 NTAPI
106 IoGetIoPriorityHint(
107     _In_ PIRP Irp)
108 {
109     return IoPriorityNormal;
110 }
111 
112 NTKERNELAPI
113 VOID
114 IoSetMasterIrpStatus(
115     _Inout_ PIRP MasterIrp,
116     _In_ NTSTATUS Status)
117 {
118     NTSTATUS MasterStatus = MasterIrp->IoStatus.Status;
119 
120     if (Status == STATUS_FT_READ_FROM_COPY)
121     {
122         return;
123     }
124 
125     if ((Status == STATUS_VERIFY_REQUIRED) ||
126         (MasterStatus == STATUS_SUCCESS && !NT_SUCCESS(Status)) ||
127         (!NT_SUCCESS(MasterStatus) && !NT_SUCCESS(Status) && Status > MasterStatus))
128     {
129         MasterIrp->IoStatus.Status = Status;
130     }
131 }
132