[FLTMGR] Stub FltGetFileNameInformationUnsafe()
[reactos.git] / drivers / input / sermouse / fdo.c
1 /*
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)
7 */
8
9 #include "sermouse.h"
10
11 #include <debug.h>
12
13 NTSTATUS NTAPI
14 SermouseAddDevice(
15 IN PDRIVER_OBJECT DriverObject,
16 IN PDEVICE_OBJECT Pdo)
17 {
18 PSERMOUSE_DRIVER_EXTENSION DriverExtension;
19 PDEVICE_OBJECT Fdo;
20 PSERMOUSE_DEVICE_EXTENSION DeviceExtension = NULL;
21 NTSTATUS Status;
22
23 TRACE_(SERMOUSE, "SermouseAddDevice called. Pdo = 0x%p\n", Pdo);
24
25 if (Pdo == NULL)
26 return STATUS_SUCCESS;
27
28 /* Create new device object */
29 DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
30 Status = IoCreateDevice(
31 DriverObject,
32 sizeof(SERMOUSE_DEVICE_EXTENSION),
33 NULL,
34 FILE_DEVICE_SERIAL_MOUSE_PORT,
35 FILE_DEVICE_SECURE_OPEN,
36 TRUE,
37 &Fdo);
38 if (!NT_SUCCESS(Status))
39 {
40 WARN_(SERMOUSE, "IoCreateDevice() failed with status 0x%08lx\n", Status);
41 goto cleanup;
42 }
43
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))
52 {
53 WARN_(SERMOUSE, "IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
54 goto cleanup;
55 }
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;
63
64 return STATUS_SUCCESS;
65
66 cleanup:
67 if (DeviceExtension)
68 {
69 if (DeviceExtension->LowerDevice)
70 IoDetachDevice(DeviceExtension->LowerDevice);
71 }
72 if (Fdo)
73 {
74 IoDeleteDevice(Fdo);
75 }
76 return Status;
77 }
78
79 NTSTATUS NTAPI
80 SermouseStartDevice(
81 IN PDEVICE_OBJECT DeviceObject,
82 IN PIRP Irp)
83 {
84 PSERMOUSE_DEVICE_EXTENSION DeviceExtension;
85 SERMOUSE_MOUSE_TYPE MouseType;
86 NTSTATUS Status;
87
88 DeviceExtension = (PSERMOUSE_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
89
90 ASSERT(DeviceExtension->PnpState == dsStopped);
91 ASSERT(DeviceExtension->LowerDevice);
92 MouseType = SermouseDetectLegacyDevice(DeviceExtension->LowerDevice);
93 if (MouseType == mtNone)
94 {
95 WARN_(SERMOUSE, "No mouse connected to Fdo %p\n",
96 DeviceExtension->LowerDevice);
97 return STATUS_DEVICE_NOT_CONNECTED;
98 }
99
100 switch (MouseType)
101 {
102 case mtMicrosoft:
103 DeviceExtension->AttributesInformation.MouseIdentifier = MOUSE_SERIAL_HARDWARE;
104 DeviceExtension->AttributesInformation.NumberOfButtons = 2;
105 break;
106 case mtLogitech:
107 DeviceExtension->AttributesInformation.MouseIdentifier = MOUSE_SERIAL_HARDWARE;
108 DeviceExtension->AttributesInformation.NumberOfButtons = 3;
109 break;
110 case mtWheelZ:
111 DeviceExtension->AttributesInformation.MouseIdentifier = WHEELMOUSE_SERIAL_HARDWARE;
112 DeviceExtension->AttributesInformation.NumberOfButtons = 3;
113 break;
114 default:
115 WARN_(SERMOUSE, "Unknown mouse type 0x%lx\n", MouseType);
116 ASSERT(FALSE);
117 return STATUS_UNSUCCESSFUL;
118 }
119
120 if (DeviceExtension->DriverExtension->NumberOfButtons != 0)
121 /* Override the number of buttons */
122 DeviceExtension->AttributesInformation.NumberOfButtons = DeviceExtension->DriverExtension->NumberOfButtons;
123
124 DeviceExtension->AttributesInformation.SampleRate = 1200 / 8;
125 DeviceExtension->AttributesInformation.InputDataQueueLength = 1;
126 DeviceExtension->MouseType = MouseType;
127 DeviceExtension->PnpState = dsStarted;
128
129 /* Start read loop */
130 Status = PsCreateSystemThread(
131 &DeviceExtension->WorkerThreadHandle,
132 (ACCESS_MASK)0L,
133 NULL,
134 NULL,
135 NULL,
136 SermouseDeviceWorker,
137 DeviceObject);
138
139 return Status;
140 }
141
142 NTSTATUS NTAPI
143 SermousePnp(
144 IN PDEVICE_OBJECT DeviceObject,
145 IN PIRP Irp)
146 {
147 ULONG MinorFunction;
148 PIO_STACK_LOCATION Stack;
149 ULONG_PTR Information = 0;
150 NTSTATUS Status;
151
152 Stack = IoGetCurrentIrpStackLocation(Irp);
153 MinorFunction = Stack->MinorFunction;
154 Information = Irp->IoStatus.Information;
155
156 switch (MinorFunction)
157 {
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
172 */
173 case IRP_MN_START_DEVICE: /* 0x0 */
174 {
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);
180 break;
181 }
182 case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x7 */
183 {
184 switch (Stack->Parameters.QueryDeviceRelations.Type)
185 {
186 case BusRelations:
187 {
188 PDEVICE_RELATIONS DeviceRelations = NULL;
189 TRACE_(SERMOUSE, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
190
191 DeviceRelations = ExAllocatePoolWithTag(PagedPool, FIELD_OFFSET(DEVICE_RELATIONS, Objects), SERMOUSE_TAG);
192 if (!DeviceRelations)
193 {
194 WARN_(SERMOUSE, "ExAllocatePoolWithTag() failed\n");
195 Status = STATUS_NO_MEMORY;
196 }
197 else
198 {
199 DeviceRelations->Count = 0;
200 Status = STATUS_SUCCESS;
201 Information = (ULONG_PTR)DeviceRelations;
202 }
203 break;
204 }
205 default:
206 {
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);
210 }
211 }
212 break;
213 }
214 default:
215 {
216 TRACE_(SERMOUSE, "IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
217 return ForwardIrpAndForget(DeviceObject, Irp);
218 }
219 }
220
221 Irp->IoStatus.Information = Information;
222 Irp->IoStatus.Status = Status;
223 IoCompleteRequest(Irp, IO_NO_INCREMENT);
224 return Status;
225 }