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)
15 IN PDRIVER_OBJECT DriverObject
,
16 IN PDEVICE_OBJECT Pdo
)
18 PSERMOUSE_DRIVER_EXTENSION DriverExtension
;
20 PSERMOUSE_DEVICE_EXTENSION DeviceExtension
= NULL
;
23 TRACE_(SERMOUSE
, "SermouseAddDevice called. Pdo = 0x%p\n", Pdo
);
26 return STATUS_SUCCESS
;
28 /* Create new device object */
29 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
30 Status
= IoCreateDevice(
32 sizeof(SERMOUSE_DEVICE_EXTENSION
),
34 FILE_DEVICE_SERIAL_MOUSE_PORT
,
35 FILE_DEVICE_SECURE_OPEN
,
38 if (!NT_SUCCESS(Status
))
40 WARN_(SERMOUSE
, "IoCreateDevice() failed with status 0x%08lx\n", Status
);
44 DeviceExtension
= (PSERMOUSE_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
45 RtlZeroMemory(DeviceExtension
, sizeof(SERMOUSE_DEVICE_EXTENSION
));
46 DeviceExtension
->MouseType
= mtNone
;
47 DeviceExtension
->PnpState
= dsStopped
;
48 DeviceExtension
->DriverExtension
= DriverExtension
;
49 KeInitializeEvent(&DeviceExtension
->StopWorkerThreadEvent
, NotificationEvent
, FALSE
);
50 Status
= IoAttachDeviceToDeviceStackSafe(Fdo
, Pdo
, &DeviceExtension
->LowerDevice
);
51 if (!NT_SUCCESS(Status
))
53 WARN_(SERMOUSE
, "IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status
);
56 if (DeviceExtension
->LowerDevice
->Flags
& DO_POWER_PAGABLE
)
57 Fdo
->Flags
|= DO_POWER_PAGABLE
;
58 if (DeviceExtension
->LowerDevice
->Flags
& DO_BUFFERED_IO
)
59 Fdo
->Flags
|= DO_BUFFERED_IO
;
60 if (DeviceExtension
->LowerDevice
->Flags
& DO_DIRECT_IO
)
61 Fdo
->Flags
|= DO_DIRECT_IO
;
62 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
64 return STATUS_SUCCESS
;
69 if (DeviceExtension
->LowerDevice
)
70 IoDetachDevice(DeviceExtension
->LowerDevice
);
81 IN PDEVICE_OBJECT DeviceObject
,
84 PSERMOUSE_DEVICE_EXTENSION DeviceExtension
;
85 SERMOUSE_MOUSE_TYPE MouseType
;
88 DeviceExtension
= (PSERMOUSE_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
90 ASSERT(DeviceExtension
->PnpState
== dsStopped
);
91 ASSERT(DeviceExtension
->LowerDevice
);
92 MouseType
= SermouseDetectLegacyDevice(DeviceExtension
->LowerDevice
);
93 if (MouseType
== mtNone
)
95 WARN_(SERMOUSE
, "No mouse connected to Fdo %p\n",
96 DeviceExtension
->LowerDevice
);
97 return STATUS_DEVICE_NOT_CONNECTED
;
103 DeviceExtension
->AttributesInformation
.MouseIdentifier
= MOUSE_SERIAL_HARDWARE
;
104 DeviceExtension
->AttributesInformation
.NumberOfButtons
= 2;
107 DeviceExtension
->AttributesInformation
.MouseIdentifier
= MOUSE_SERIAL_HARDWARE
;
108 DeviceExtension
->AttributesInformation
.NumberOfButtons
= 3;
111 DeviceExtension
->AttributesInformation
.MouseIdentifier
= WHEELMOUSE_SERIAL_HARDWARE
;
112 DeviceExtension
->AttributesInformation
.NumberOfButtons
= 3;
115 WARN_(SERMOUSE
, "Unknown mouse type 0x%lx\n", MouseType
);
117 return STATUS_UNSUCCESSFUL
;
120 if (DeviceExtension
->DriverExtension
->NumberOfButtons
!= 0)
121 /* Override the number of buttons */
122 DeviceExtension
->AttributesInformation
.NumberOfButtons
= DeviceExtension
->DriverExtension
->NumberOfButtons
;
124 DeviceExtension
->AttributesInformation
.SampleRate
= 1200 / 8;
125 DeviceExtension
->AttributesInformation
.InputDataQueueLength
= 1;
126 DeviceExtension
->MouseType
= MouseType
;
127 DeviceExtension
->PnpState
= dsStarted
;
129 /* Start read loop */
130 Status
= PsCreateSystemThread(
131 &DeviceExtension
->WorkerThreadHandle
,
136 SermouseDeviceWorker
,
144 IN PDEVICE_OBJECT DeviceObject
,
148 PIO_STACK_LOCATION Stack
;
149 ULONG_PTR Information
= 0;
152 Stack
= IoGetCurrentIrpStackLocation(Irp
);
153 MinorFunction
= Stack
->MinorFunction
;
154 Information
= Irp
->IoStatus
.Information
;
156 switch (MinorFunction
)
158 /* FIXME: do all these minor functions
159 IRP_MN_QUERY_REMOVE_DEVICE 0x1
160 IRP_MN_REMOVE_DEVICE 0x2
161 IRP_MN_CANCEL_REMOVE_DEVICE 0x3
162 IRP_MN_STOP_DEVICE 0x4
163 IRP_MN_QUERY_STOP_DEVICE 0x5
164 IRP_MN_CANCEL_STOP_DEVICE 0x6
165 IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations (optional) 0x7
166 IRP_MN_QUERY_INTERFACE (optional) 0x8
167 IRP_MN_QUERY_CAPABILITIES (optional) 0x9
168 IRP_MN_FILTER_RESOURCE_REQUIREMENTS (optional or required) 0xd
169 IRP_MN_QUERY_PNP_DEVICE_STATE (optional) 0x14
170 IRP_MN_DEVICE_USAGE_NOTIFICATION (required or optional) 0x16
171 IRP_MN_SURPRISE_REMOVAL 0x17
173 case IRP_MN_START_DEVICE
: /* 0x0 */
175 TRACE_(SERMOUSE
, "IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
176 /* Call lower driver */
177 Status
= ForwardIrpAndWait(DeviceObject
, Irp
);
178 if (NT_SUCCESS(Status
))
179 Status
= SermouseStartDevice(DeviceObject
, Irp
);
182 case IRP_MN_QUERY_DEVICE_RELATIONS
: /* 0x7 */
184 switch (Stack
->Parameters
.QueryDeviceRelations
.Type
)
188 PDEVICE_RELATIONS DeviceRelations
= NULL
;
189 TRACE_(SERMOUSE
, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
191 DeviceRelations
= ExAllocatePoolWithTag(PagedPool
, FIELD_OFFSET(DEVICE_RELATIONS
, Objects
), SERMOUSE_TAG
);
192 if (!DeviceRelations
)
194 WARN_(SERMOUSE
, "ExAllocatePoolWithTag() failed\n");
195 Status
= STATUS_NO_MEMORY
;
199 DeviceRelations
->Count
= 0;
200 Status
= STATUS_SUCCESS
;
201 Information
= (ULONG_PTR
)DeviceRelations
;
207 TRACE_(SERMOUSE
, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
208 Stack
->Parameters
.QueryDeviceRelations
.Type
);
209 return ForwardIrpAndForget(DeviceObject
, Irp
);
216 TRACE_(SERMOUSE
, "IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction
);
217 return ForwardIrpAndForget(DeviceObject
, Irp
);
221 Irp
->IoStatus
.Information
= Information
;
222 Irp
->IoStatus
.Status
= Status
;
223 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);