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_INTERNAL_DEVICE_CONTROL operations
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 SermouseInternalDeviceControl(
15 	IN PDEVICE_OBJECT DeviceObject,
16 	IN PIRP Irp)
17 {
18 	PSERMOUSE_DEVICE_EXTENSION DeviceExtension;
19 	PIO_STACK_LOCATION Stack;
20 	NTSTATUS Status;
21 
22 	DeviceExtension = (PSERMOUSE_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
23 	Stack = IoGetCurrentIrpStackLocation(Irp);
24 
25 	switch (Stack->Parameters.DeviceIoControl.IoControlCode)
26 	{
27 		case IOCTL_INTERNAL_MOUSE_CONNECT:
28 		{
29 			TRACE_(SERMOUSE, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_CONNECT\n");
30 			DeviceExtension->ConnectData =
31 				*((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer);
32 			Status = STATUS_SUCCESS;
33 			break;
34 		}
35 		case IOCTL_INTERNAL_MOUSE_DISCONNECT:
36 		{
37 			TRACE_(SERMOUSE, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_MOUSE_DISCONNECT\n");
38 
39 			/* Ask read loop to end */
40 			KeSetEvent(&DeviceExtension->StopWorkerThreadEvent, (KPRIORITY)0, FALSE);
41 			Status = STATUS_SUCCESS;
42 			break;
43 		}
44 		case IOCTL_MOUSE_QUERY_ATTRIBUTES:
45 		{
46 			TRACE_(SERMOUSE, "IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_MOUSE_QUERY_ATTRIBUTES\n");
47 			if (Stack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(MOUSE_ATTRIBUTES))
48 			{
49 				*(PMOUSE_ATTRIBUTES)Irp->AssociatedIrp.SystemBuffer =
50 					DeviceExtension->AttributesInformation;
51 				Irp->IoStatus.Information = sizeof(MOUSE_ATTRIBUTES);
52 				Status = STATUS_SUCCESS;
53 			}
54 			else
55 			{
56 				Status = STATUS_BUFFER_TOO_SMALL;
57 			}
58 			break;
59 		}
60 		default:
61 		{
62 			WARN_(SERMOUSE, "IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n",
63 				Stack->Parameters.DeviceIoControl.IoControlCode);
64 			ASSERT(FALSE);
65 			Status = STATUS_INVALID_DEVICE_REQUEST;
66 			break;
67 		}
68 	}
69 
70 	Irp->IoStatus.Status = Status;
71 	if (Status == STATUS_PENDING)
72 	{
73 		IoMarkIrpPending(Irp);
74 		IoStartPacket(DeviceObject, Irp, NULL, NULL);
75 	}
76 	else
77 	{
78 		IoCompleteRequest(Irp, IO_NO_INCREMENT);
79 	}
80 
81 	return Status;
82 }
83