- ULONG is always >= 0
[reactos.git] / reactos / drivers / base / beep / beep.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/dd/beep/beep.c
6 * PURPOSE: BEEP device driver
7 * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
8 * UPDATE HISTORY:
9 * 30/01/99 Created
10 * 16/10/99 Minor fixes
11 */
12
13 /* INCLUDES ****************************************************************/
14
15 #include <ntddk.h>
16 #include <ntddbeep.h>
17 #include <limits.h>
18
19 #define NDEBUG
20 #include <debug.h>
21
22 NTSTATUS STDCALL
23 DriverEntry(PDRIVER_OBJECT DriverObject,
24 PUNICODE_STRING RegistryPath);
25
26 /* TYEPEDEFS ***************************************************************/
27
28 typedef struct _BEEP_DEVICE_EXTENSION
29 {
30 KDPC Dpc;
31 KTIMER Timer;
32 KEVENT Event;
33 BOOLEAN BeepOn;
34 } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
35
36
37 /* FUNCTIONS ***************************************************************/
38
39 static VOID STDCALL
40 BeepDPC(PKDPC Dpc,
41 PVOID DeferredContext,
42 PVOID SystemArgument1,
43 PVOID SystemArgument2)
44 {
45 PDEVICE_EXTENSION DeviceExtension = DeferredContext;
46
47 DPRINT("BeepDPC() called!\n");
48
49 HalMakeBeep(0);
50 DeviceExtension->BeepOn = FALSE;
51 KeSetEvent(&DeviceExtension->Event,
52 0,
53 FALSE);
54
55 DPRINT("BeepDPC() finished!\n");
56 }
57
58
59 static NTSTATUS STDCALL
60 BeepCreate(
61 PDEVICE_OBJECT DeviceObject,
62 PIRP Irp)
63 /*
64 * FUNCTION: Handles user mode requests
65 * ARGUMENTS:
66 * DeviceObject = Device for request
67 * Irp = I/O request packet describing request
68 * RETURNS: Success or failure
69 */
70 {
71 DPRINT("BeepCreate() called!\n");
72
73 Irp->IoStatus.Status = STATUS_SUCCESS;
74 Irp->IoStatus.Information = 0;
75 IoCompleteRequest(Irp,
76 IO_NO_INCREMENT);
77
78 return(STATUS_SUCCESS);
79 }
80
81
82 static NTSTATUS STDCALL
83 BeepClose(PDEVICE_OBJECT DeviceObject,
84 PIRP Irp)
85 /*
86 * FUNCTION: Handles user mode requests
87 * ARGUMENTS:
88 * DeviceObject = Device for request
89 * Irp = I/O request packet describing request
90 * RETURNS: Success or failure
91 */
92 {
93 PDEVICE_EXTENSION DeviceExtension;
94 NTSTATUS Status;
95
96 DPRINT("BeepClose() called!\n");
97
98 DeviceExtension = DeviceObject->DeviceExtension;
99 if (DeviceExtension->BeepOn == TRUE)
100 {
101 HalMakeBeep(0);
102 DeviceExtension->BeepOn = FALSE;
103 KeCancelTimer(&DeviceExtension->Timer);
104 }
105
106 Status = STATUS_SUCCESS;
107
108 Irp->IoStatus.Status = Status;
109 Irp->IoStatus.Information = 0;
110 IoCompleteRequest(Irp,
111 IO_NO_INCREMENT);
112
113 return(Status);
114 }
115
116
117 static NTSTATUS STDCALL
118 BeepCleanup(PDEVICE_OBJECT DeviceObject,
119 PIRP Irp)
120 /*
121 * FUNCTION: Handles user mode requests
122 * ARGUMENTS:
123 * DeviceObject = Device for request
124 * Irp = I/O request packet describing request
125 * RETURNS: Success or failure
126 */
127 {
128 DPRINT("BeepCleanup() called!\n");
129
130 Irp->IoStatus.Status = STATUS_SUCCESS;
131 Irp->IoStatus.Information = 0;
132 IoCompleteRequest(Irp,
133 IO_NO_INCREMENT);
134
135 return(STATUS_SUCCESS);
136 }
137
138
139 static NTSTATUS STDCALL
140 BeepDeviceControl(PDEVICE_OBJECT DeviceObject,
141 PIRP Irp)
142 /*
143 * FUNCTION: Handles user mode requests
144 * ARGUMENTS:
145 * DeviceObject = Device for request
146 * Irp = I/O request packet describing request
147 * RETURNS: Success or failure
148 */
149 {
150 PIO_STACK_LOCATION Stack;
151 PDEVICE_EXTENSION DeviceExtension;
152 PBEEP_SET_PARAMETERS BeepParam;
153 LARGE_INTEGER DueTime;
154
155 DPRINT("BeepDeviceControl() called!\n");
156
157 DeviceExtension = DeviceObject->DeviceExtension;
158 Stack = IoGetCurrentIrpStackLocation(Irp);
159 BeepParam = (PBEEP_SET_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
160
161 Irp->IoStatus.Information = 0;
162
163 if (Stack->Parameters.DeviceIoControl.IoControlCode != IOCTL_BEEP_SET)
164 {
165 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
166 IoCompleteRequest(Irp,
167 IO_NO_INCREMENT);
168 return(STATUS_NOT_IMPLEMENTED);
169 }
170
171 if ((Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(BEEP_SET_PARAMETERS))
172 || (BeepParam->Frequency < BEEP_FREQUENCY_MINIMUM)
173 || (BeepParam->Frequency > BEEP_FREQUENCY_MAXIMUM))
174 {
175 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
176 IoCompleteRequest(Irp,
177 IO_NO_INCREMENT);
178 return(STATUS_INVALID_PARAMETER);
179 }
180
181 DueTime.QuadPart = 0;
182
183 /* do the beep!! */
184 DPRINT("Beep:\n Freq: %lu Hz\n Dur: %lu ms\n",
185 BeepParam->Frequency,
186 BeepParam->Duration);
187 if (BeepParam->Duration > 0)
188 {
189 DueTime.QuadPart = (LONGLONG)BeepParam->Duration * -10000;
190
191 KeSetTimer(&DeviceExtension->Timer,
192 DueTime,
193 &DeviceExtension->Dpc);
194
195 HalMakeBeep(BeepParam->Frequency);
196 DeviceExtension->BeepOn = TRUE;
197 KeWaitForSingleObject(&DeviceExtension->Event,
198 Executive,
199 KernelMode,
200 FALSE,
201 NULL);
202 }
203 else if (BeepParam->Duration == ULONG_MAX)
204 {
205 if (DeviceExtension->BeepOn == TRUE)
206 {
207 HalMakeBeep(0);
208 DeviceExtension->BeepOn = FALSE;
209 }
210 else
211 {
212 HalMakeBeep(BeepParam->Frequency);
213 DeviceExtension->BeepOn = TRUE;
214 }
215 }
216
217 DPRINT("Did the beep!\n");
218
219 Irp->IoStatus.Status = STATUS_SUCCESS;
220 IoCompleteRequest(Irp,
221 IO_NO_INCREMENT);
222 return(STATUS_SUCCESS);
223 }
224
225
226 static VOID STDCALL
227 BeepUnload(PDRIVER_OBJECT DriverObject)
228 {
229 DPRINT("BeepUnload() called!\n");
230 }
231
232
233 NTSTATUS STDCALL
234 DriverEntry(PDRIVER_OBJECT DriverObject,
235 PUNICODE_STRING RegistryPath)
236 /*
237 * FUNCTION: Called by the system to initalize the driver
238 * ARGUMENTS:
239 * DriverObject = object describing this driver
240 * RegistryPath = path to our configuration entries
241 * RETURNS: Success or failure
242 */
243 {
244 PDEVICE_EXTENSION DeviceExtension;
245 PDEVICE_OBJECT DeviceObject;
246 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Beep");
247 NTSTATUS Status;
248
249 DPRINT("Beep Device Driver 0.0.3\n");
250
251 DriverObject->Flags = 0;
252 DriverObject->MajorFunction[IRP_MJ_CREATE] = BeepCreate;
253 DriverObject->MajorFunction[IRP_MJ_CLOSE] = BeepClose;
254 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = BeepCleanup;
255 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = BeepDeviceControl;
256 DriverObject->DriverUnload = BeepUnload;
257
258 Status = IoCreateDevice(DriverObject,
259 sizeof(DEVICE_EXTENSION),
260 &DeviceName,
261 FILE_DEVICE_BEEP,
262 0,
263 FALSE,
264 &DeviceObject);
265 if (!NT_SUCCESS(Status))
266 return Status;
267
268 /* set up device extension */
269 DeviceExtension = DeviceObject->DeviceExtension;
270 DeviceExtension->BeepOn = FALSE;
271
272 KeInitializeDpc(&DeviceExtension->Dpc,
273 BeepDPC,
274 DeviceExtension);
275 KeInitializeTimer(&DeviceExtension->Timer);
276 KeInitializeEvent(&DeviceExtension->Event,
277 SynchronizationEvent,
278 FALSE);
279
280 return(STATUS_SUCCESS);
281 }
282
283 /* EOF */