2 * PROJECT: ReactOS Serial mouse driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/input/sermouse/fdo.c
5 * PURPOSE: IRP_MJ_PNP operations for FDOs
6 * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
13 IN PDRIVER_OBJECT DriverObject
,
14 IN PDEVICE_OBJECT Pdo
)
16 PSERMOUSE_DRIVER_EXTENSION DriverExtension
;
18 PSERMOUSE_DEVICE_EXTENSION DeviceExtension
= NULL
;
21 TRACE_(SERMOUSE
, "SermouseAddDevice called. Pdo = 0x%p\n", Pdo
);
24 return STATUS_SUCCESS
;
26 /* Create new device object */
27 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
28 Status
= IoCreateDevice(
30 sizeof(SERMOUSE_DEVICE_EXTENSION
),
32 FILE_DEVICE_SERIAL_MOUSE_PORT
,
33 FILE_DEVICE_SECURE_OPEN
,
36 if (!NT_SUCCESS(Status
))
38 WARN_(SERMOUSE
, "IoCreateDevice() failed with status 0x%08lx\n", Status
);
42 DeviceExtension
= (PSERMOUSE_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
43 RtlZeroMemory(DeviceExtension
, sizeof(SERMOUSE_DEVICE_EXTENSION
));
44 DeviceExtension
->MouseType
= mtNone
;
45 DeviceExtension
->PnpState
= dsStopped
;
46 DeviceExtension
->DriverExtension
= DriverExtension
;
47 KeInitializeEvent(&DeviceExtension
->StopWorkerThreadEvent
, NotificationEvent
, FALSE
);
48 Status
= IoAttachDeviceToDeviceStackSafe(Fdo
, Pdo
, &DeviceExtension
->LowerDevice
);
49 if (!NT_SUCCESS(Status
))
51 WARN_(SERMOUSE
, "IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status
);
54 if (DeviceExtension
->LowerDevice
->Flags
& DO_POWER_PAGABLE
)
55 Fdo
->Flags
|= DO_POWER_PAGABLE
;
56 if (DeviceExtension
->LowerDevice
->Flags
& DO_BUFFERED_IO
)
57 Fdo
->Flags
|= DO_BUFFERED_IO
;
58 if (DeviceExtension
->LowerDevice
->Flags
& DO_DIRECT_IO
)
59 Fdo
->Flags
|= DO_DIRECT_IO
;
60 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
62 return STATUS_SUCCESS
;
67 if (DeviceExtension
->LowerDevice
)
68 IoDetachDevice(DeviceExtension
->LowerDevice
);
79 IN PDEVICE_OBJECT DeviceObject
,
82 PSERMOUSE_DEVICE_EXTENSION DeviceExtension
;
83 SERMOUSE_MOUSE_TYPE MouseType
;
86 DeviceExtension
= (PSERMOUSE_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
88 ASSERT(DeviceExtension
->PnpState
== dsStopped
);
89 ASSERT(DeviceExtension
->LowerDevice
);
90 MouseType
= SermouseDetectLegacyDevice(DeviceExtension
->LowerDevice
);
91 if (MouseType
== mtNone
)
93 WARN_(SERMOUSE
, "No mouse connected to Fdo %p\n",
94 DeviceExtension
->LowerDevice
);
95 return STATUS_DEVICE_NOT_CONNECTED
;
101 DeviceExtension
->AttributesInformation
.MouseIdentifier
= MOUSE_SERIAL_HARDWARE
;
102 DeviceExtension
->AttributesInformation
.NumberOfButtons
= 2;
105 DeviceExtension
->AttributesInformation
.MouseIdentifier
= MOUSE_SERIAL_HARDWARE
;
106 DeviceExtension
->AttributesInformation
.NumberOfButtons
= 3;
109 DeviceExtension
->AttributesInformation
.MouseIdentifier
= WHEELMOUSE_SERIAL_HARDWARE
;
110 DeviceExtension
->AttributesInformation
.NumberOfButtons
= 3;
113 WARN_(SERMOUSE
, "Unknown mouse type 0x%lx\n", MouseType
);
115 return STATUS_UNSUCCESSFUL
;
118 if (DeviceExtension
->DriverExtension
->NumberOfButtons
!= 0)
119 /* Override the number of buttons */
120 DeviceExtension
->AttributesInformation
.NumberOfButtons
= DeviceExtension
->DriverExtension
->NumberOfButtons
;
122 DeviceExtension
->AttributesInformation
.SampleRate
= 1200 / 8;
123 DeviceExtension
->AttributesInformation
.InputDataQueueLength
= 1;
124 DeviceExtension
->MouseType
= MouseType
;
125 DeviceExtension
->PnpState
= dsStarted
;
127 /* Start read loop */
128 Status
= PsCreateSystemThread(
129 &DeviceExtension
->WorkerThreadHandle
,
134 SermouseDeviceWorker
,
142 IN PDEVICE_OBJECT DeviceObject
,
146 PIO_STACK_LOCATION Stack
;
147 ULONG_PTR Information
= 0;
150 Stack
= IoGetCurrentIrpStackLocation(Irp
);
151 MinorFunction
= Stack
->MinorFunction
;
152 Information
= Irp
->IoStatus
.Information
;
154 switch (MinorFunction
)
156 /* FIXME: do all these minor functions
157 IRP_MN_QUERY_REMOVE_DEVICE 0x1
158 IRP_MN_REMOVE_DEVICE 0x2
159 IRP_MN_CANCEL_REMOVE_DEVICE 0x3
160 IRP_MN_STOP_DEVICE 0x4
161 IRP_MN_QUERY_STOP_DEVICE 0x5
162 IRP_MN_CANCEL_STOP_DEVICE 0x6
163 IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations (optional) 0x7
164 IRP_MN_QUERY_INTERFACE (optional) 0x8
165 IRP_MN_QUERY_CAPABILITIES (optional) 0x9
166 IRP_MN_FILTER_RESOURCE_REQUIREMENTS (optional or required) 0xd
167 IRP_MN_QUERY_PNP_DEVICE_STATE (optional) 0x14
168 IRP_MN_DEVICE_USAGE_NOTIFICATION (required or optional) 0x16
169 IRP_MN_SURPRISE_REMOVAL 0x17
171 case IRP_MN_START_DEVICE
: /* 0x0 */
173 TRACE_(SERMOUSE
, "IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
174 /* Call lower driver */
175 Status
= ForwardIrpAndWait(DeviceObject
, Irp
);
176 if (NT_SUCCESS(Status
))
177 Status
= SermouseStartDevice(DeviceObject
, Irp
);
180 case IRP_MN_QUERY_DEVICE_RELATIONS
: /* 0x7 */
182 switch (Stack
->Parameters
.QueryDeviceRelations
.Type
)
186 PDEVICE_RELATIONS DeviceRelations
= NULL
;
187 TRACE_(SERMOUSE
, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
189 DeviceRelations
= ExAllocatePoolWithTag(PagedPool
, FIELD_OFFSET(DEVICE_RELATIONS
, Objects
), SERMOUSE_TAG
);
190 if (!DeviceRelations
)
192 WARN_(SERMOUSE
, "ExAllocatePoolWithTag() failed\n");
193 Status
= STATUS_NO_MEMORY
;
197 DeviceRelations
->Count
= 0;
198 Status
= STATUS_SUCCESS
;
199 Information
= (ULONG_PTR
)DeviceRelations
;
205 TRACE_(SERMOUSE
, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
206 Stack
->Parameters
.QueryDeviceRelations
.Type
);
207 return ForwardIrpAndForget(DeviceObject
, Irp
);
214 TRACE_(SERMOUSE
, "IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction
);
215 return ForwardIrpAndForget(DeviceObject
, Irp
);
219 Irp
->IoStatus
.Information
= Information
;
220 Irp
->IoStatus
.Status
= Status
;
221 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);