New macros InitializeUnicodeString(), RtlInitUnicodeStringFromLiteral() and UNICODE_S...
[reactos.git] / reactos / drivers / input / psaux / psaux.c
1 /*
2
3 ** PS/2 driver 0.0.1
4 ** Written by Jason Filby (jasonfilby@yahoo.com)
5 ** For ReactOS (www.reactos.com)
6
7 ** Handles the keyboard and mouse on the PS/2 ports
8
9 ** TODO: Fix detect_ps2_port(void) so that it works under BOCHs
10 Implement mouse button support
11
12 */
13
14 #include <ddk/ntddk.h>
15 #include "../include/mouse.h"
16 #include "mouse.h"
17 #include "psaux.h"
18
19 BOOLEAN STDCALL
20 MouseSynchronizeRoutine(PVOID Context)
21 {
22 PIRP Irp = (PIRP)Context;
23 PMOUSE_INPUT_DATA rec = (PMOUSE_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
24 PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
25 ULONG NrToRead = stk->Parameters.Read.Length/sizeof(MOUSE_INPUT_DATA);
26 int i;
27
28 if ((stk->Parameters.Read.Length/sizeof(MOUSE_INPUT_DATA))==NrToRead)
29 {
30 return(TRUE);
31 }
32
33 MouseDataRequired=stk->Parameters.Read.Length/sizeof(MOUSE_INPUT_DATA);
34 MouseDataRead=NrToRead;
35 CurrentIrp=Irp;
36
37 return(FALSE);
38 }
39
40 VOID STDCALL
41 PS2MouseStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
42 {
43 PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
44
45 if (KeSynchronizeExecution(DeviceExtension->MouseInterrupt, MouseSynchronizeRoutine, Irp))
46 {
47 Irp->IoStatus.Status = STATUS_SUCCESS;
48 Irp->IoStatus.Information = 0;
49 IoCompleteRequest(Irp, IO_NO_INCREMENT);
50 IoStartNextPacket(DeviceObject, FALSE);
51 }
52 }
53
54 NTSTATUS STDCALL
55 PS2MouseDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
56 {
57 PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
58 NTSTATUS Status;
59
60 switch (stk->MajorFunction)
61 {
62 case IRP_MJ_CREATE:
63 if (AlreadyOpened == TRUE)
64 {
65 Status = STATUS_SUCCESS;
66 }
67 else
68 {
69 Status = STATUS_SUCCESS;
70 AlreadyOpened = TRUE;
71 }
72 break;
73
74 case IRP_MJ_CLOSE:
75 Status = STATUS_SUCCESS;
76 break;
77
78 default:
79 DbgPrint("NOT IMPLEMENTED\n");
80 Status = STATUS_NOT_IMPLEMENTED;
81 break;
82 }
83
84 if (Status==STATUS_PENDING)
85 {
86 IoMarkIrpPending(Irp);
87 }
88 else
89 {
90 Irp->IoStatus.Status = Status;
91 Irp->IoStatus.Information = 0;
92 IoCompleteRequest(Irp,IO_NO_INCREMENT);
93 }
94 return(Status);
95 }
96
97 VOID PS2MouseInitializeDataQueue(PVOID Context)
98 {
99 ;
100 /* PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceExtension;
101
102 DeviceExtension->InputDataCount = 0;
103 DeviceExtension->MouseInputData = ExAllocatePool(NonPagedPool, sizeof(MOUSE_INPUT_DATA) * MOUSE_BUFFER_SIZE); */
104 }
105
106 NTSTATUS STDCALL
107 PS2MouseInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
108 {
109 PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
110 PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
111 NTSTATUS status;
112
113 switch(Stack->Parameters.DeviceIoControl.IoControlCode)
114 {
115 case IOCTL_INTERNAL_MOUSE_CONNECT:
116
117 DeviceExtension->ClassInformation =
118 *((PCLASS_INFORMATION)Stack->Parameters.DeviceIoControl.Type3InputBuffer);
119
120 // Reinitialize the port input data queue synchronously
121 KeSynchronizeExecution(DeviceExtension->MouseInterrupt,
122 (PKSYNCHRONIZE_ROUTINE)PS2MouseInitializeDataQueue, DeviceExtension);
123
124 status = STATUS_SUCCESS;
125 break;
126
127 default:
128 status = STATUS_INVALID_DEVICE_REQUEST;
129 break;
130 }
131
132 Irp->IoStatus.Status = status;
133 if (status == STATUS_PENDING) {
134 IoMarkIrpPending(Irp);
135 IoStartPacket(DeviceObject, Irp, NULL, NULL);
136 } else {
137 IoCompleteRequest(Irp, IO_NO_INCREMENT);
138 }
139
140 return status;
141 }
142
143 VOID PS2MouseIsrDpc(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
144 {
145 PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
146
147 (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassInformation.CallBack)(
148 DeviceExtension->ClassInformation.DeviceObject,
149 DeviceExtension->MouseInputData,
150 NULL,
151 &DeviceExtension->InputDataCount);
152
153 DeviceExtension->InputDataCount = 0;
154 }
155
156 NTSTATUS STDCALL
157 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
158 {
159 PDEVICE_OBJECT DeviceObject;
160 UNICODE_STRING DeviceName;
161 UNICODE_STRING SymlinkName;
162 PDEVICE_EXTENSION DeviceExtension;
163
164 if(detect_ps2_port() == TRUE)
165 {
166 } else
167 return STATUS_UNSUCCESSFUL;
168
169 DriverObject->MajorFunction[IRP_MJ_CREATE] = PS2MouseDispatch;
170 DriverObject->MajorFunction[IRP_MJ_CLOSE] = PS2MouseDispatch;
171 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = PS2MouseInternalDeviceControl;
172 DriverObject->DriverStartIo = PS2MouseStartIo;
173
174 RtlInitUnicodeStringFromLiteral(&DeviceName,
175 L"\\Device\\Mouse"); // FIXME: find correct device name
176 IoCreateDevice(DriverObject,
177 sizeof(DEVICE_EXTENSION),
178 &DeviceName,
179 FILE_DEVICE_SERIAL_MOUSE_PORT, // FIXME: this isn't really a serial mouse port driver
180 0,
181 TRUE,
182 &DeviceObject);
183 DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
184
185 RtlInitUnicodeStringFromLiteral(&SymlinkName,
186 L"\\??\\Mouse"); // FIXME: find correct device name
187 IoCreateSymbolicLink(&SymlinkName, &DeviceName);
188
189 DeviceExtension = DeviceObject->DeviceExtension;
190 KeInitializeDpc(&DeviceExtension->IsrDpc, (PKDEFERRED_ROUTINE)PS2MouseIsrDpc, DeviceObject);
191 KeInitializeDpc(&DeviceExtension->IsrDpcRetry, (PKDEFERRED_ROUTINE)PS2MouseIsrDpc, DeviceObject);
192
193 mouse_init(DeviceObject);
194
195 return(STATUS_SUCCESS);
196 }