ReactOS 0.4.15-dev-7924-g5949c20
pnpirp.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Shortcuts for sending different IRP_MJ_PNP requests
5 * COPYRIGHT: Copyright 2010 Sir Richard <sir_richard@svn.reactos.org>
6 * Copyright 2020 Victor Perevertkin <victor.perevertkin@reactos.org>
7 */
8
9#include <ntoskrnl.h>
10#define NDEBUG
11#include <debug.h>
12
16 _In_ PIO_STACK_LOCATION IoStackLocation,
18{
19 PIRP Irp;
20 PIO_STACK_LOCATION IrpStack;
24 PDEVICE_OBJECT TopDeviceObject;
25 PAGED_CODE();
26
27 /* Call the top of the device stack */
29
30 /* Allocate an IRP */
31 Irp = IoAllocateIrp(TopDeviceObject->StackSize, FALSE);
32 if (!Irp)
33 {
34 ObDereferenceObject(TopDeviceObject);
36 }
37
38 /* Initialize to failure */
39 Irp->IoStatus.Status = IoStatusBlock.Status = STATUS_NOT_SUPPORTED;
40 Irp->IoStatus.Information = IoStatusBlock.Information = 0;
41
42 /* Special case for IRP_MN_FILTER_RESOURCE_REQUIREMENTS */
43 if ((IoStackLocation->MajorFunction == IRP_MJ_PNP) &&
44 (IoStackLocation->MinorFunction == IRP_MN_FILTER_RESOURCE_REQUIREMENTS))
45 {
46 /* Copy the resource requirements list into the IOSB */
47 Irp->IoStatus.Information =
48 IoStatusBlock.Information = (ULONG_PTR)IoStackLocation->Parameters.FilterResourceRequirements.IoResourceRequirementList;
49 }
50
51 /* Initialize the event */
53
54 /* Set them up */
55 Irp->UserIosb = &IoStatusBlock;
56 Irp->UserEvent = &Event;
57
58 /* Queue the IRP */
59 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
61
62 /* Copy-in the stack */
64 *IrpStack = *IoStackLocation;
65
66 /* Call the driver */
67 Status = IoCallDriver(TopDeviceObject, Irp);
68 /* Otherwise we may get stuck here or have IoStatusBlock not populated */
71 {
72 /* Wait for it */
75 }
76
77 /* Remove the reference */
78 ObDereferenceObject(TopDeviceObject);
79
80 /* Return the information */
82 return Status;
83}
84
85// IRP_MN_START_DEVICE (0x00)
89{
90 PAGED_CODE();
91
94
95 PVOID info;
97 .MajorFunction = IRP_MJ_PNP,
98 .MinorFunction = IRP_MN_START_DEVICE,
99 .Parameters.StartDevice.AllocatedResources = DeviceNode->ResourceList,
100 .Parameters.StartDevice.AllocatedResourcesTranslated = DeviceNode->ResourceListTranslated
101 };
102
103 // Vista+ does an asynchronous call
104 NTSTATUS status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, &info);
105 DeviceNode->CompletionStatus = status;
106 return status;
107}
108
109// IRP_MN_STOP_DEVICE (0x04)
113{
114 PAGED_CODE();
115
118
119 PVOID info;
121 .MajorFunction = IRP_MJ_PNP,
122 .MinorFunction = IRP_MN_STOP_DEVICE
123 };
124
125 // Drivers should never fail a IRP_MN_STOP_DEVICE request
126 NTSTATUS status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, &info);
128 return status;
129}
130
131// IRP_MN_QUERY_STOP_DEVICE (0x05)
135{
136 PAGED_CODE();
137
140
141 PVOID info;
143 .MajorFunction = IRP_MJ_PNP,
144 .MinorFunction = IRP_MN_QUERY_STOP_DEVICE
145 };
146
147 NTSTATUS status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, &info);
148 DeviceNode->CompletionStatus = status;
149 return status;
150}
151
152// IRP_MN_CANCEL_STOP_DEVICE (0x06)
156{
157 PAGED_CODE();
158
161
162 PVOID info;
164 .MajorFunction = IRP_MJ_PNP,
165 .MinorFunction = IRP_MN_CANCEL_STOP_DEVICE
166 };
167
168 // in fact we don't care which status is returned here
169 NTSTATUS status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, &info);
171 return status;
172}
173
174// IRP_MN_QUERY_DEVICE_RELATIONS (0x07)
179{
180 PAGED_CODE();
181
184
186 .MajorFunction = IRP_MJ_PNP,
187 .MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS,
188 .Parameters.QueryDeviceRelations.Type = Type
189 };
190
191 // Vista+ does an asynchronous call
192 NTSTATUS status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject,
193 &stack,
194 (PVOID)&DeviceNode->OverUsed1.PendingDeviceRelations);
195 DeviceNode->CompletionStatus = status;
196 return status;
197}
198
199// IRP_MN_QUERY_RESOURCES (0x0A)
204{
205 PAGED_CODE();
206
208
209 ULONG_PTR longRes;
211 .MajorFunction = IRP_MJ_PNP,
212 .MinorFunction = IRP_MN_QUERY_RESOURCES
213 };
214
216 status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, (PVOID)&longRes);
217 if (NT_SUCCESS(status))
218 {
219 *Resources = (PVOID)longRes;
220 }
221
222 return status;
223}
224
225// IRP_MN_QUERY_RESOURCE_REQUIREMENTS (0x0B)
230{
231 PAGED_CODE();
232
234
235 ULONG_PTR longRes;
237 .MajorFunction = IRP_MJ_PNP,
239 };
240
242 status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, (PVOID)&longRes);
243 if (NT_SUCCESS(status))
244 {
245 *Resources = (PVOID)longRes;
246 }
247
248 return status;
249}
250
251// IRP_MN_QUERY_DEVICE_TEXT (0x0C)
257 _Out_ PWSTR *DeviceText)
258{
259 PAGED_CODE();
260
263
264 ULONG_PTR longText;
266 .MajorFunction = IRP_MJ_PNP,
267 .MinorFunction = IRP_MN_QUERY_DEVICE_TEXT,
268 .Parameters.QueryDeviceText.DeviceTextType = Type,
269 .Parameters.QueryDeviceText.LocaleId = LocaleId
270 };
271
273 status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, (PVOID)&longText);
274 if (NT_SUCCESS(status))
275 {
276 *DeviceText = (PVOID)longText;
277 }
278
279 return status;
280}
281
282// IRP_MN_QUERY_PNP_DEVICE_STATE (0x14)
287{
288 PAGED_CODE();
289
292 DeviceNode->State == DeviceNodeStarted);
293
294 ULONG_PTR longState;
296 .MajorFunction = IRP_MJ_PNP,
297 .MinorFunction = IRP_MN_QUERY_PNP_DEVICE_STATE
298 };
299
301 status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, (PVOID)&longState);
302 if (NT_SUCCESS(status))
303 {
304 *DeviceState = longState;
305 }
306
307 return status;
308}
#define PAGED_CODE()
@ DeviceNode
Definition: Node.h:9
Type
Definition: Type.h:7
LONG NTSTATUS
Definition: precomp.h:26
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
Definition: _stack.h:55
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ULONG_PTR
Definition: config.h:101
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
Status
Definition: gdiplustypes.h:25
#define ASSERT(a)
Definition: mode.c:44
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define KernelMode
Definition: asm.h:34
@ DeviceNodeStartPostWork
Definition: iotypes.h:428
@ DeviceNodeStarted
Definition: iotypes.h:429
@ DeviceNodeResourcesAssigned
Definition: iotypes.h:425
@ DeviceNodeUninitialized
Definition: iotypes.h:422
@ DeviceNodeQueryStopped
Definition: iotypes.h:430
@ SynchronizationEvent
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
VOID NTAPI IoQueueThreadIrp(IN PIRP Irp)
Definition: irp.c:1954
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IoCallDriver
Definition: irp.c:1225
BOOLEAN NTAPI KeAreAllApcsDisabled(VOID)
Definition: apc.c:985
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
NTSTATUS PiIrpQueryResources(_In_ PDEVICE_NODE DeviceNode, _Out_ PCM_RESOURCE_LIST *Resources)
Definition: pnpirp.c:201
NTSTATUS PiIrpStartDevice(_In_ PDEVICE_NODE DeviceNode)
Definition: pnpirp.c:87
NTSTATUS PiIrpQueryPnPDeviceState(_In_ PDEVICE_NODE DeviceNode, _Out_ PPNP_DEVICE_STATE DeviceState)
Definition: pnpirp.c:284
NTSTATUS PiIrpCancelStopDevice(_In_ PDEVICE_NODE DeviceNode)
Definition: pnpirp.c:154
NTSTATUS IopSynchronousCall(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIO_STACK_LOCATION IoStackLocation, _Out_ PVOID *Information)
Definition: pnpirp.c:14
NTSTATUS PiIrpQueryResourceRequirements(_In_ PDEVICE_NODE DeviceNode, _Out_ PIO_RESOURCE_REQUIREMENTS_LIST *Resources)
Definition: pnpirp.c:227
NTSTATUS PiIrpQueryStopDevice(_In_ PDEVICE_NODE DeviceNode)
Definition: pnpirp.c:133
NTSTATUS PiIrpStopDevice(_In_ PDEVICE_NODE DeviceNode)
Definition: pnpirp.c:111
NTSTATUS PiIrpQueryDeviceText(_In_ PDEVICE_NODE DeviceNode, _In_ LCID LocaleId, _In_ DEVICE_TEXT_TYPE Type, _Out_ PWSTR *DeviceText)
Definition: pnpirp.c:253
NTSTATUS PiIrpQueryDeviceRelations(_In_ PDEVICE_NODE DeviceNode, _In_ DEVICE_RELATION_TYPE Type)
Definition: pnpirp.c:176
DWORD LCID
Definition: nls.h:13
Definition: ps.c:97
uint16_t * PWSTR
Definition: typedefs.h:56
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFDEVICE _Out_ PWDF_DEVICE_STATE DeviceState
Definition: wdfdevice.h:1999
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING _In_ PCUNICODE_STRING _In_ LCID LocaleId
Definition: wdfpdo.h:437
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IRP_MN_CANCEL_STOP_DEVICE
#define IRP_MN_QUERY_PNP_DEVICE_STATE
#define IRP_MN_START_DEVICE
#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_QUERY_DEVICE_TEXT
#define IRP_MN_QUERY_RESOURCES
#define IRP_MN_STOP_DEVICE
enum _DEVICE_TEXT_TYPE DEVICE_TEXT_TYPE
ULONG * PPNP_DEVICE_STATE
Definition: iotypes.h:997
enum _DEVICE_RELATION_TYPE DEVICE_RELATION_TYPE
@ Executive
Definition: ketypes.h:415
#define ObDereferenceObject
Definition: obfuncs.h:203