migrate substitution keywords to SVN
[reactos.git] / reactos / drivers / dd / 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 <ddk/ntddk.h>
16 #include <ddk/ntddbeep.h>
17 #include <rosrtl/string.h>
18
19 #define NDEBUG
20 #include <debug.h>
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(
57 PDEVICE_OBJECT DeviceObject,
58 PIRP Irp)
59 /*
60 * FUNCTION: Handles user mode requests
61 * ARGUMENTS:
62 * DeviceObject = Device for request
63 * Irp = I/O request packet describing request
64 * RETURNS: Success or failure
65 */
66 {
67 DPRINT("BeepCreate() called!\n");
68
69 Irp->IoStatus.Status = STATUS_SUCCESS;
70 Irp->IoStatus.Information = 0;
71 IoCompleteRequest(Irp,
72 IO_NO_INCREMENT);
73
74 return(STATUS_SUCCESS);
75 }
76
77
78 static NTSTATUS STDCALL
79 BeepClose(PDEVICE_OBJECT DeviceObject,
80 PIRP Irp)
81 /*
82 * FUNCTION: Handles user mode requests
83 * ARGUMENTS:
84 * DeviceObject = Device for request
85 * Irp = I/O request packet describing request
86 * RETURNS: Success or failure
87 */
88 {
89 PDEVICE_EXTENSION DeviceExtension;
90 NTSTATUS Status;
91
92 DPRINT("BeepClose() called!\n");
93
94 DeviceExtension = DeviceObject->DeviceExtension;
95 if (DeviceExtension->BeepOn == TRUE)
96 {
97 HalMakeBeep(0);
98 DeviceExtension->BeepOn = FALSE;
99 KeCancelTimer(&DeviceExtension->Timer);
100 }
101
102 Status = STATUS_SUCCESS;
103
104 Irp->IoStatus.Status = Status;
105 Irp->IoStatus.Information = 0;
106 IoCompleteRequest(Irp,
107 IO_NO_INCREMENT);
108
109 return(Status);
110 }
111
112
113 static NTSTATUS STDCALL
114 BeepCleanup(PDEVICE_OBJECT DeviceObject,
115 PIRP Irp)
116 /*
117 * FUNCTION: Handles user mode requests
118 * ARGUMENTS:
119 * DeviceObject = Device for request
120 * Irp = I/O request packet describing request
121 * RETURNS: Success or failure
122 */
123 {
124 DPRINT("BeepCleanup() called!\n");
125
126 Irp->IoStatus.Status = STATUS_SUCCESS;
127 Irp->IoStatus.Information = 0;
128 IoCompleteRequest(Irp,
129 IO_NO_INCREMENT);
130
131 return(STATUS_SUCCESS);
132 }
133
134
135 static NTSTATUS STDCALL
136 BeepDeviceControl(PDEVICE_OBJECT DeviceObject,
137 PIRP Irp)
138 /*
139 * FUNCTION: Handles user mode requests
140 * ARGUMENTS:
141 * DeviceObject = Device for request
142 * Irp = I/O request packet describing request
143 * RETURNS: Success or failure
144 */
145 {
146 PIO_STACK_LOCATION Stack;
147 PDEVICE_EXTENSION DeviceExtension;
148 PBEEP_SET_PARAMETERS BeepParam;
149 LARGE_INTEGER DueTime;
150
151 DPRINT("BeepDeviceControl() called!\n");
152
153 DeviceExtension = DeviceObject->DeviceExtension;
154 Stack = IoGetCurrentIrpStackLocation(Irp);
155 BeepParam = (PBEEP_SET_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
156
157 Irp->IoStatus.Information = 0;
158
159 if (Stack->Parameters.DeviceIoControl.IoControlCode != IOCTL_BEEP_SET)
160 {
161 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
162 IoCompleteRequest(Irp,
163 IO_NO_INCREMENT);
164 return(STATUS_NOT_IMPLEMENTED);
165 }
166
167 if ((Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(BEEP_SET_PARAMETERS))
168 || (BeepParam->Frequency < BEEP_FREQUENCY_MINIMUM)
169 || (BeepParam->Frequency > BEEP_FREQUENCY_MAXIMUM))
170 {
171 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
172 IoCompleteRequest(Irp,
173 IO_NO_INCREMENT);
174 return(STATUS_INVALID_PARAMETER);
175 }
176
177 DueTime.QuadPart = 0;
178
179 /* do the beep!! */
180 DPRINT("Beep:\n Freq: %lu Hz\n Dur: %lu ms\n",
181 pbsp->Frequency,
182 pbsp->Duration);
183
184 if (BeepParam->Duration >= 0)
185 {
186 DueTime.QuadPart = (LONGLONG)BeepParam->Duration * -10000;
187
188 KeSetTimer(&DeviceExtension->Timer,
189 DueTime,
190 &DeviceExtension->Dpc);
191
192 HalMakeBeep(BeepParam->Frequency);
193 DeviceExtension->BeepOn = TRUE;
194 KeWaitForSingleObject(&DeviceExtension->Event,
195 Executive,
196 KernelMode,
197 FALSE,
198 NULL);
199 }
200 else if (BeepParam->Duration == (DWORD)-1)
201 {
202 if (DeviceExtension->BeepOn == TRUE)
203 {
204 HalMakeBeep(0);
205 DeviceExtension->BeepOn = FALSE;
206 }
207 else
208 {
209 HalMakeBeep(BeepParam->Frequency);
210 DeviceExtension->BeepOn = TRUE;
211 }
212 }
213
214 DPRINT("Did the beep!\n");
215
216 Irp->IoStatus.Status = STATUS_SUCCESS;
217 IoCompleteRequest(Irp,
218 IO_NO_INCREMENT);
219 return(STATUS_SUCCESS);
220 }
221
222
223 static VOID STDCALL
224 BeepUnload(PDRIVER_OBJECT DriverObject)
225 {
226 DPRINT("BeepUnload() called!\n");
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 = ROS_STRING_INITIALIZER(L"\\Device\\Beep");
244 UNICODE_STRING SymlinkName = ROS_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 */