ReactOS 0.4.15-dev-7942-gd23573b
pnp.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS InPort (Bus) Mouse Driver
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Plug and Play requests handling
5 * COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com)
6 */
7
8/* INCLUDES *******************************************************************/
9
10#include "inport.h"
11
12#define NDEBUG
13#include <debug.h>
14
15/* FUNCTIONS ******************************************************************/
16
17CODE_SEG("PAGE")
23{
26 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor, DescriptorTranslated;
27 ULONG i;
28 ULONG RawVector;
29 BOOLEAN FoundBasePort = FALSE, FoundIrq = FALSE;
30 PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
32
33 PAGED_CODE();
34
35 ASSERT(DeviceExtension->State == dsStopped);
36
37 if (!IoForwardIrpSynchronously(DeviceExtension->Ldo, Irp))
38 {
40 goto Complete;
41 }
42 Status = Irp->IoStatus.Status;
43 if (!NT_SUCCESS(Status))
44 {
45 DPRINT1("LDO failed to start 0x%X\n", Status);
46 goto Complete;
47 }
48
49 AllocatedResources = IrpSp->Parameters.StartDevice.AllocatedResources;
50 AllocatedResourcesTranslated = IrpSp->Parameters.StartDevice.AllocatedResourcesTranslated;
52 {
53 DPRINT1("No allocated resources\n");
55 goto Complete;
56 }
57
58 if (AllocatedResources->Count != 1)
59 DPRINT1("Expected FullList count is 1, got %d\n", AllocatedResources->Count);
60
61 for (i = 0; i < AllocatedResources->List[0].PartialResourceList.Count; i++)
62 {
63 Descriptor = &AllocatedResources->List[0].PartialResourceList.PartialDescriptors[i];
64 DescriptorTranslated = &AllocatedResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[i];
65
66 switch (Descriptor->Type)
67 {
69 {
70 DPRINT("[%p:%X:%X] I/O ports at [%p-%p]\n",
72 Descriptor->ShareDisposition,
73 Descriptor->Flags,
74 Descriptor->u.Port.Start.LowPart,
75 Descriptor->u.Port.Start.LowPart + (Descriptor->u.Port.Length - 1));
76
77 if (!FoundBasePort)
78 {
79 DeviceExtension->IoBase = ULongToPtr(Descriptor->u.Port.Start.u.LowPart);
80
81 FoundBasePort = TRUE;
82 }
83
84 break;
85 }
86
88 {
89 DPRINT("[%p:%X:%X] INT Vec %d Lev %d Aff %IX\n",
91 Descriptor->ShareDisposition,
92 Descriptor->Flags,
93 Descriptor->u.Interrupt.Vector,
94 Descriptor->u.Interrupt.Level,
95 Descriptor->u.Interrupt.Affinity);
96
97 if (!FoundIrq)
98 {
99 DeviceExtension->InterruptVector = DescriptorTranslated->u.Interrupt.Vector;
100 DeviceExtension->InterruptLevel = (KIRQL)DescriptorTranslated->u.Interrupt.Level;
101 if (DescriptorTranslated->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
102 DeviceExtension->InterruptMode = Latched;
103 else
104 DeviceExtension->InterruptMode = LevelSensitive;
105 DeviceExtension->InterruptShared = (DescriptorTranslated->ShareDisposition == CmResourceShareShared);
106 DeviceExtension->InterruptAffinity = DescriptorTranslated->u.Interrupt.Affinity;
107 RawVector = Descriptor->u.Interrupt.Vector;
108
109 FoundIrq = TRUE;
110 }
111
112 break;
113 }
114
115 default:
116 DPRINT("[%p:%X:%X] Unrecognized resource type %X\n",
118 Descriptor->ShareDisposition,
119 Descriptor->Flags,
120 Descriptor->Type);
121 break;
122 }
123 }
124
125 if (!FoundBasePort || !FoundIrq)
126 {
127 DPRINT1("The device resources were not found\n");
129 goto Complete;
130 }
131
132 DPRINT("I/O base at %p\n", DeviceExtension->IoBase);
133 DPRINT("IRQ %d\n", RawVector);
134
135 Status = InPortWmiRegistration(DeviceExtension);
136 if (!NT_SUCCESS(Status))
137 {
138 DPRINT1("WMI registration failed 0x%X\n", Status);
139 goto Complete;
140 }
141
142 InPortInitializeMouse(DeviceExtension);
143
144 Status = IoConnectInterrupt(&DeviceExtension->InterruptObject,
145 InPortIsr,
146 DeviceExtension,
147 NULL,
148 DeviceExtension->InterruptVector,
149 DeviceExtension->InterruptLevel,
150 DeviceExtension->InterruptLevel,
151 DeviceExtension->InterruptMode,
152 DeviceExtension->InterruptShared,
153 DeviceExtension->InterruptAffinity,
154 FALSE);
155 if (!NT_SUCCESS(Status))
156 {
157 DPRINT1("Could not connect to interrupt %d\n", DeviceExtension->InterruptVector);
158 goto Complete;
159 }
160
163 DeviceExtension);
164
165 DeviceExtension->State = dsStarted;
166
168 Irp->IoStatus.Status = Status;
170
171 return Status;
172}
173
174CODE_SEG("PAGE")
176NTAPI
180{
182 BOOLEAN IsStarted;
183 PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
184
185 PAGED_CODE();
186
187 InPortWmiDeRegistration(DeviceExtension);
188
189 IsStarted = (DeviceExtension->State == dsStarted);
190
191 DeviceExtension->State = dsRemoved;
192
193 Irp->IoStatus.Status = STATUS_SUCCESS;
195 Status = IoCallDriver(DeviceExtension->Ldo, Irp);
196
197 IoReleaseRemoveLockAndWait(&DeviceExtension->RemoveLock, Irp);
198
199 /* Device is active */
200 if (IsStarted)
201 {
204 DeviceExtension);
205
206 IoDisconnectInterrupt(DeviceExtension->InterruptObject);
207
208 /* Flush DPC for ISR */
210 }
211
212 IoDetachDevice(DeviceExtension->Ldo);
214
215 return Status;
216}
217
218CODE_SEG("PAGE")
220NTAPI
224{
226 PINPORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
228
229 PAGED_CODE();
230
231 DPRINT("%s(%p, %p) %X\n",
233
234 Status = IoAcquireRemoveLock(&DeviceExtension->RemoveLock, Irp);
235 if (!NT_SUCCESS(Status))
236 {
237 Irp->IoStatus.Information = 0;
238 Irp->IoStatus.Status = Status;
240
241 return Status;
242 }
243
244 switch (IrpSp->MinorFunction)
245 {
248 break;
249
252
254 /* Device cannot work with other resources */
255 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
257 break;
258
264 Irp->IoStatus.Status = STATUS_SUCCESS;
266 Status = IoCallDriver(DeviceExtension->Ldo, Irp);
267 break;
268
269 default:
271 Status = IoCallDriver(DeviceExtension->Ldo, Irp);
272 break;
273 }
274
275 IoReleaseRemoveLock(&DeviceExtension->RemoveLock, Irp);
276
277 return Status;
278}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
#define CODE_SEG(...)
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define ULongToPtr(ul)
Definition: basetsd.h:92
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI KeFlushQueuedDpcs(VOID)
Definition: dpc.c:919
@ dsRemoved
Definition: pci.h:38
#define __FUNCTION__
Definition: types.h:116
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
VOID NTAPI InPortInitializeMouse(_In_ PINPORT_DEVICE_EXTENSION DeviceExtension)
Definition: hardware.c:350
NTSTATUS NTAPI InPortRemoveDevice(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: pnp.c:177
NTSTATUS NTAPI InPortPnp(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: pnp.c:221
NTSTATUS NTAPI InPortStartDevice(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: pnp.c:20
UCHAR KIRQL
Definition: env_spec_w32.h:591
pRequest Complete(RequestStatus)
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define CmResourceTypePort
Definition: hwresource.cpp:123
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
KSERVICE_ROUTINE InPortIsr
Definition: inport.h:107
KSYNCHRONIZE_ROUTINE InPortStopMouse
Definition: inport.h:113
NTSTATUS NTAPI InPortWmiRegistration(_Inout_ PINPORT_DEVICE_EXTENSION DeviceExtension)
Definition: wmi.c:118
KSYNCHRONIZE_ROUTINE InPortStartMouse
Definition: inport.h:111
NTSTATUS NTAPI InPortWmiDeRegistration(_Inout_ PINPORT_DEVICE_EXTENSION DeviceExtension)
Definition: wmi.c:140
@ dsStopped
Definition: isapnp.h:34
@ dsStarted
Definition: isapnp.h:35
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
_Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PCM_RESOURCE_LIST * AllocatedResources
Definition: ndis.h:4643
_Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PCM_RESOURCE_LIST _Inout_opt_ PCM_RESOURCE_LIST * AllocatedResourcesTranslated
Definition: ndis.h:4644
#define CM_RESOURCE_INTERRUPT_LATCHED
Definition: cmtypes.h:144
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define IoCompleteRequest
Definition: irp.c:1240
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:141
NTSTATUS NTAPI IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN KAFFINITY ProcessorEnableMask, IN BOOLEAN FloatingSave)
Definition: irq.c:22
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:237
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:619
@ Latched
Definition: miniport.h:81
@ LevelSensitive
Definition: miniport.h:80
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@393 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@393::@396 Interrupt
PDEVICE_OBJECT Ldo
Definition: inport.h:46
KINTERRUPT_MODE InterruptMode
Definition: inport.h:57
IO_REMOVE_LOCK RemoveLock
Definition: inport.h:48
PKINTERRUPT InterruptObject
Definition: inport.h:54
BOOLEAN InterruptShared
Definition: inport.h:58
INPORT_DEVICE_STATE State
Definition: inport.h:47
KAFFINITY InterruptAffinity
Definition: inport.h:59
struct _IO_STACK_LOCATION::@3978::@4015 StartDevice
union _IO_STACK_LOCATION::@1564 Parameters
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
@ CmResourceShareShared
Definition: cmtypes.h:243
#define IoAcquireRemoveLock(RemoveLock, Tag)
#define IoReleaseRemoveLockAndWait(_RemoveLock, _Tag)
Definition: iofuncs.h:2774
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2764
#define IRP_MN_CANCEL_STOP_DEVICE
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_START_DEVICE
#define IRP_MN_REMOVE_DEVICE
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_STOP_DEVICE
#define IRP_MN_QUERY_REMOVE_DEVICE