ReactOS  0.4.15-dev-2703-g05fb0f1
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;
22  KEVENT Event;
24  PDEVICE_OBJECT TopDeviceObject;
25  PAGED_CODE();
26 
27  /* Call the top of the device stack */
28  TopDeviceObject = IoGetAttachedDeviceReference(DeviceObject);
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 */
63  IrpStack = IoGetNextIrpStackLocation(Irp);
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 */
70  if (Status == STATUS_PENDING)
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)
110 NTSTATUS
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)
132 NTSTATUS
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)
153 NTSTATUS
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)
175 NTSTATUS
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_DEVICE_TEXT (0x0C)
200 NTSTATUS
205  _Out_ PWSTR *DeviceText)
206 {
207  PAGED_CODE();
208 
211 
212  ULONG_PTR longText;
214  .MajorFunction = IRP_MJ_PNP,
215  .MinorFunction = IRP_MN_QUERY_DEVICE_TEXT,
216  .Parameters.QueryDeviceText.DeviceTextType = Type,
217  .Parameters.QueryDeviceText.LocaleId = LocaleId
218  };
219 
221  status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, (PVOID)&longText);
222  if (NT_SUCCESS(status))
223  {
224  *DeviceText = (PVOID)longText;
225  }
226 
227  return status;
228 }
229 
230 // IRP_MN_QUERY_PNP_DEVICE_STATE (0x14)
231 NTSTATUS
235 {
236  PAGED_CODE();
237 
240  DeviceNode->State == DeviceNodeStarted);
241 
242  ULONG_PTR longState;
244  .MajorFunction = IRP_MJ_PNP,
245  .MinorFunction = IRP_MN_QUERY_PNP_DEVICE_STATE
246  };
247 
249  status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject, &stack, (PVOID)&longState);
250  if (NT_SUCCESS(status))
251  {
252  *DeviceState = longState;
253  }
254 
255  return status;
256 }
return STATUS_NOT_SUPPORTED
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
BOOLEAN NTAPI KeAreAllApcsDisabled(VOID)
Definition: apc.c:985
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
NTSTATUS PiIrpQueryPnPDeviceState(_In_ PDEVICE_NODE DeviceNode, _Out_ PPNP_DEVICE_STATE DeviceState)
Definition: pnpirp.c:232
NTSTATUS PiIrpQueryStopDevice(_In_ PDEVICE_NODE DeviceNode)
Definition: pnpirp.c:133
NTSTATUS IopSynchronousCall(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIO_STACK_LOCATION IoStackLocation, _Out_ PVOID *Information)
Definition: pnpirp.c:14
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS
uint16_t * PWSTR
Definition: typedefs.h:56
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
DWORD LCID
Definition: nls.h:13
VOID NTAPI IoQueueThreadIrp(IN PIRP Irp)
Definition: irp.c:1954
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
enum _DEVICE_TEXT_TYPE DEVICE_TEXT_TYPE
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1044
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFDEVICE _Out_ PWDF_DEVICE_STATE DeviceState
Definition: wdfdevice.h:1996
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
ULONG * PPNP_DEVICE_STATE
Definition: iotypes.h:997
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:467
#define _Out_
Definition: no_sal2.h:160
void * PVOID
Definition: retypes.h:9
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
enum _DEVICE_RELATION_TYPE DEVICE_RELATION_TYPE
#define IRP_MN_QUERY_STOP_DEVICE
Definition: _stack.h:47
Status
Definition: gdiplustypes.h:24
#define IRP_MN_STOP_DEVICE
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IRP_MN_START_DEVICE
#define ObDereferenceObject
Definition: obfuncs.h:203
Type
Definition: Type.h:6
#define IRP_MN_QUERY_DEVICE_TEXT
NTSTATUS PiIrpStartDevice(_In_ PDEVICE_NODE DeviceNode)
Definition: pnpirp.c:87
Definition: Node.h:9
struct _test_info info[]
Definition: SetCursorPos.c:19
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING _In_ PCUNICODE_STRING _In_ LCID LocaleId
Definition: wdfpdo.h:430
NTSTATUS PiIrpQueryDeviceText(_In_ PDEVICE_NODE DeviceNode, _In_ LCID LocaleId, _In_ DEVICE_TEXT_TYPE Type, _Out_ PWSTR *DeviceText)
Definition: pnpirp.c:201
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
NTSTATUS PiIrpCancelStopDevice(_In_ PDEVICE_NODE DeviceNode)
Definition: pnpirp.c:154
#define _In_
Definition: no_sal2.h:158
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define ULONG_PTR
Definition: config.h:101
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IRP_MN_CANCEL_STOP_DEVICE
NTSTATUS PiIrpStopDevice(_In_ PDEVICE_NODE DeviceNode)
Definition: pnpirp.c:111
static SERVICE_STATUS status
Definition: service.c:31
#define IRP_MN_QUERY_PNP_DEVICE_STATE
#define PAGED_CODE()
NTSTATUS PiIrpQueryDeviceRelations(_In_ PDEVICE_NODE DeviceNode, _In_ DEVICE_RELATION_TYPE Type)
Definition: pnpirp.c:176
Definition: ps.c:97