ReactOS  0.4.15-dev-3187-ge372f2b
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 
17 CODE_SEG("PAGE")
19 NTAPI
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  {
68  case CmResourceTypePort:
69  {
70  DPRINT("[%p:%X:%X] I/O ports at [%p-%p]\n",
71  Descriptor,
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",
90  Descriptor,
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",
117  Descriptor,
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 
161  KeSynchronizeExecution(DeviceExtension->InterruptObject,
163  DeviceExtension);
164 
165  DeviceExtension->State = dsStarted;
166 
167 Complete:
168  Irp->IoStatus.Status = Status;
170 
171  return Status;
172 }
173 
174 CODE_SEG("PAGE")
175 NTSTATUS
176 NTAPI
179  _Inout_ PIRP Irp)
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  {
202  KeSynchronizeExecution(DeviceExtension->InterruptObject,
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 
218 CODE_SEG("PAGE")
219 NTSTATUS
220 NTAPI
223  _Inout_ PIRP Irp)
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  {
246  case IRP_MN_START_DEVICE:
248  break;
249 
252 
254  /* Device cannot work with other resources */
255  Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
257  break;
258 
261  case IRP_MN_STOP_DEVICE:
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 }
Definition: pci.h:35
PDEVICE_OBJECT Ldo
Definition: inport.h:46
#define IRP_MN_CANCEL_REMOVE_DEVICE
KSYNCHRONIZE_ROUTINE InPortStartMouse
Definition: inport.h:111
INPORT_DEVICE_STATE State
Definition: inport.h:47
#define ULongToPtr(ul)
Definition: basetsd.h:92
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:339
#define _Inout_
Definition: ms_sal.h:378
NTSTATUS NTAPI InPortWmiRegistration(_Inout_ PINPORT_DEVICE_EXTENSION DeviceExtension)
Definition: wmi.c:118
_Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PDEVICE_OBJECT _Inout_opt_ PCM_RESOURCE_LIST * AllocatedResources
Definition: ndis.h:4640
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
LONG NTSTATUS
Definition: precomp.h:26
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2764
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
KSERVICE_ROUTINE InPortIsr
Definition: inport.h:107
KINTERRUPT_MODE InterruptMode
Definition: inport.h:57
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define CmResourceTypePort
Definition: hwresource.cpp:123
KSYNCHRONIZE_ROUTINE InPortStopMouse
Definition: inport.h:113
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@376 u
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define IRP_MN_QUERY_REMOVE_DEVICE
pRequest Complete(RequestStatus)
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
_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:4640
KAFFINITY InterruptAffinity
Definition: inport.h:59
unsigned char BOOLEAN
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:140
#define _In_
Definition: ms_sal.h:308
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS NTAPI InPortRemoveDevice(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: pnp.c:177
VOID NTAPI InPortInitializeMouse(_In_ PINPORT_DEVICE_EXTENSION DeviceExtension)
Definition: hardware.c:340
PKINTERRUPT InterruptObject
Definition: inport.h:54
#define IRP_MN_QUERY_STOP_DEVICE
Status
Definition: gdiplustypes.h:24
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define IRP_MN_STOP_DEVICE
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IRP_MN_START_DEVICE
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
IO_REMOVE_LOCK RemoveLock
Definition: inport.h:48
NTSTATUS NTAPI InPortPnp(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: pnp.c:221
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
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
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
NTSTATUS NTAPI InPortStartDevice(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: pnp.c:20
#define DPRINT1
Definition: precomp.h:8
#define CM_RESOURCE_INTERRUPT_LATCHED
Definition: cmtypes.h:144
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:165
#define IoReleaseRemoveLockAndWait(_RemoveLock, _Tag)
Definition: iofuncs.h:2774
#define IRP_MN_CANCEL_STOP_DEVICE
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@376::@379 Interrupt
#define DPRINT
Definition: sndvol32.h:71
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:619
#define __FUNCTION__
Definition: types.h:112
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
VOID NTAPI KeFlushQueuedDpcs(VOID)
Definition: dpc.c:919
#define IoAcquireRemoveLock(RemoveLock, Tag)
NTSTATUS NTAPI InPortWmiDeRegistration(_Inout_ PINPORT_DEVICE_EXTENSION DeviceExtension)
Definition: wmi.c:140
BOOLEAN InterruptShared
Definition: inport.h:58
#define PAGED_CODE()