Branch setupapi (again)
[reactos.git] / reactos / drivers / video / videoprt / dispatch.c
1 /*
2 * VideoPort driver
3 *
4 * Copyright (C) 2002, 2003, 2004 ReactOS Team
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; see the file COPYING.LIB.
18 * If not, write to the Free Software Foundation,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * $Id$
22 */
23
24 #include "videoprt.h"
25
26 /* EXTERNAL FUNCTIONS *********************************************************/
27
28 typedef PVOID PHAL_RESET_DISPLAY_PARAMETERS;
29 VOID STDCALL HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters);
30 VOID STDCALL HalReleaseDisplayOwnership();
31
32 /* GLOBAL VARIABLES ***********************************************************/
33
34 PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL;
35
36 /* PRIVATE FUNCTIONS **********************************************************/
37
38 /*
39 * Reset display to blue screen
40 */
41
42 BOOLEAN STDCALL
43 IntVideoPortResetDisplayParameters(ULONG Columns, ULONG Rows)
44 {
45 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
46
47 if (ResetDisplayParametersDeviceExtension == NULL)
48 return FALSE;
49
50 DriverExtension = ResetDisplayParametersDeviceExtension->DriverExtension;
51
52 if (DriverExtension->InitializationData.HwResetHw != NULL)
53 {
54 if (DriverExtension->InitializationData.HwResetHw(
55 &ResetDisplayParametersDeviceExtension->MiniPortDeviceExtension,
56 Columns, Rows))
57 {
58 ResetDisplayParametersDeviceExtension = NULL;
59 return TRUE;
60 }
61 }
62
63 ResetDisplayParametersDeviceExtension = NULL;
64 return FALSE;
65 }
66
67 NTSTATUS STDCALL
68 IntVideoPortAddDevice(
69 IN PDRIVER_OBJECT DriverObject,
70 IN PDEVICE_OBJECT PhysicalDeviceObject)
71 {
72 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
73
74 /*
75 * Get the initialization data we saved in VideoPortInitialize.
76 */
77
78 DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
79
80 /*
81 * Use generic routine to find the adapter and create device object.
82 */
83
84 return IntVideoPortFindAdapter(
85 DriverObject,
86 DriverExtension,
87 PhysicalDeviceObject);
88 }
89
90 /*
91 * IntVideoPortDispatchOpen
92 *
93 * Answer requests for Open calls.
94 *
95 * Run Level
96 * PASSIVE_LEVEL
97 */
98
99 NTSTATUS STDCALL
100 IntVideoPortDispatchOpen(
101 IN PDEVICE_OBJECT DeviceObject,
102 IN PIRP Irp)
103 {
104 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
105 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
106
107 DPRINT("IntVideoPortDispatchOpen\n");
108
109 if (CsrssInitialized == FALSE)
110 {
111 /*
112 * We know the first open call will be from the CSRSS process
113 * to let us know its handle.
114 */
115
116 DPRINT("Referencing CSRSS\n");
117 Csrss = PsGetCurrentProcess();
118 DPRINT("Csrss %p\n", Csrss);
119
120 CsrssInitialized = TRUE;
121
122 Irp->IoStatus.Information = FILE_OPENED;
123 IoCompleteRequest(Irp, IO_NO_INCREMENT);
124
125 return STATUS_SUCCESS;
126 }
127
128 DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
129 DriverExtension = DeviceExtension->DriverExtension;
130
131 if (DriverExtension->InitializationData.HwInitialize(&DeviceExtension->MiniPortDeviceExtension))
132 {
133 Irp->IoStatus.Status = STATUS_SUCCESS;
134
135 InterlockedIncrement((PLONG)&DeviceExtension->DeviceOpened);
136
137 /*
138 * Storing the device extension pointer in a static variable is an
139 * ugly hack. Unfortunately, we need it in VideoPortResetDisplayParameters
140 * and HalAcquireDisplayOwnership doesn't allow us to pass a userdata
141 * parameter. On the bright side, the DISPLAY device is opened
142 * exclusively, so there can be only one device extension active at
143 * any point in time.
144 */
145
146 ResetDisplayParametersDeviceExtension = DeviceExtension;
147 HalAcquireDisplayOwnership(IntVideoPortResetDisplayParameters);
148 }
149 else
150 {
151 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
152 }
153
154 Irp->IoStatus.Information = FILE_OPENED;
155 IoCompleteRequest(Irp, IO_NO_INCREMENT);
156
157 return STATUS_SUCCESS;
158 }
159
160 /*
161 * IntVideoPortDispatchClose
162 *
163 * Answer requests for Close calls.
164 *
165 * Run Level
166 * PASSIVE_LEVEL
167 */
168
169 NTSTATUS STDCALL
170 IntVideoPortDispatchClose(
171 IN PDEVICE_OBJECT DeviceObject,
172 IN PIRP Irp)
173 {
174 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
175
176 DPRINT("IntVideoPortDispatchClose\n");
177
178 DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
179 if (DeviceExtension->DeviceOpened >= 1 &&
180 InterlockedDecrement((PLONG)&DeviceExtension->DeviceOpened) == 0)
181 {
182 ResetDisplayParametersDeviceExtension = DeviceExtension;
183 HalReleaseDisplayOwnership();
184 }
185
186 Irp->IoStatus.Status = STATUS_SUCCESS;
187 IoCompleteRequest(Irp, IO_NO_INCREMENT);
188
189 return STATUS_SUCCESS;
190 }
191
192 /*
193 * IntVideoPortDispatchDeviceControl
194 *
195 * Answer requests for device control calls.
196 *
197 * Run Level
198 * PASSIVE_LEVEL
199 */
200
201 NTSTATUS STDCALL
202 IntVideoPortDispatchDeviceControl(
203 IN PDEVICE_OBJECT DeviceObject,
204 IN PIRP Irp)
205 {
206 PIO_STACK_LOCATION IrpStack;
207 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
208 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
209 PVIDEO_REQUEST_PACKET vrp;
210 NTSTATUS Status;
211
212 DPRINT("IntVideoPortDispatchDeviceControl\n");
213
214 IrpStack = IoGetCurrentIrpStackLocation(Irp);
215 DeviceExtension = DeviceObject->DeviceExtension;
216 DriverExtension = DeviceExtension->DriverExtension;
217
218 /* Translate the IRP to a VRP */
219 vrp = ExAllocatePool(NonPagedPool, sizeof(VIDEO_REQUEST_PACKET));
220 if (NULL == vrp)
221 {
222 return STATUS_NO_MEMORY;
223 }
224
225 vrp->StatusBlock = (PSTATUS_BLOCK)&(Irp->IoStatus);
226 vrp->IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
227
228 DPRINT("- IoControlCode: %x\n", vrp->IoControlCode);
229
230 /* We're assuming METHOD_BUFFERED */
231 vrp->InputBuffer = Irp->AssociatedIrp.SystemBuffer;
232 vrp->InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
233 vrp->OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
234 vrp->OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
235
236 /* Call the Miniport Driver with the VRP */
237 DriverExtension->InitializationData.HwStartIO(
238 &DeviceExtension->MiniPortDeviceExtension,
239 vrp);
240
241 /* Free the VRP */
242 ExFreePool(vrp);
243
244 DPRINT("- Returned status: %x\n", Irp->IoStatus.Status);
245
246 if (Irp->IoStatus.Status != STATUS_SUCCESS)
247 {
248 /* Map from win32 error codes to NT status values. */
249 switch (Irp->IoStatus.Status)
250 {
251 case ERROR_NOT_ENOUGH_MEMORY: Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; break;
252 case ERROR_MORE_DATA: Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; break;
253 case ERROR_INVALID_FUNCTION: Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; break;
254 case ERROR_INVALID_PARAMETER: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; break;
255 case ERROR_INSUFFICIENT_BUFFER: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; break;
256 case ERROR_DEV_NOT_EXIST: Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST; break;
257 case ERROR_IO_PENDING: Irp->IoStatus.Status = STATUS_PENDING; break;
258 }
259 }
260
261 Status = Irp->IoStatus.Status;
262 IoCompleteRequest(Irp, IO_NO_INCREMENT);
263
264 return Status;
265 }
266
267 NTSTATUS STDCALL
268 IntVideoPortDispatchPnp(
269 IN PDEVICE_OBJECT DeviceObject,
270 IN PIRP Irp)
271 {
272 PIO_STACK_LOCATION IrpSp;
273
274 IrpSp = IoGetCurrentIrpStackLocation(Irp);
275
276 switch (IrpSp->MinorFunction)
277 {
278 case IRP_MN_START_DEVICE:
279
280 case IRP_MN_REMOVE_DEVICE:
281 case IRP_MN_QUERY_REMOVE_DEVICE:
282 case IRP_MN_CANCEL_REMOVE_DEVICE:
283 case IRP_MN_SURPRISE_REMOVAL:
284
285 case IRP_MN_STOP_DEVICE:
286 case IRP_MN_QUERY_STOP_DEVICE:
287 case IRP_MN_CANCEL_STOP_DEVICE:
288 Irp->IoStatus.Status = STATUS_SUCCESS;
289 Irp->IoStatus.Information = 0;
290 IoCompleteRequest(Irp, IO_NO_INCREMENT);
291
292 return STATUS_SUCCESS;
293 }
294
295 return STATUS_NOT_IMPLEMENTED;
296 }
297
298 NTSTATUS STDCALL
299 IntVideoPortDispatchCleanup(
300 IN PDEVICE_OBJECT DeviceObject,
301 IN PIRP Irp)
302 {
303 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
304
305 DeviceExtension = DeviceObject->DeviceExtension;
306 RtlFreeUnicodeString(&DeviceExtension->RegistryPath);
307
308 Irp->IoStatus.Status = STATUS_SUCCESS;
309 Irp->IoStatus.Information = 0;
310 IoCompleteRequest(Irp, IO_NO_INCREMENT);
311
312 return STATUS_SUCCESS;
313 }
314
315 NTSTATUS STDCALL
316 IntVideoPortDispatchPower(
317 IN PDEVICE_OBJECT DeviceObject,
318 IN PIRP Irp)
319 {
320 return STATUS_NOT_IMPLEMENTED;
321 }
322
323 VOID STDCALL
324 IntVideoPortUnload(PDRIVER_OBJECT DriverObject)
325 {
326 }