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