ReactOS 0.4.15-dev-8127-g6338913
sndblst.c
Go to the documentation of this file.
1/*
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/dd/sndblst/sndblst.c
6 * PURPOSE: Sound Blaster / SB Pro / SB 16 driver
7 * PROGRAMMER: Andrew Greenwood
8 * UPDATE HISTORY:
9 * Sept 28, 2003: Copied from mpu401.c as a template
10 */
11
12/* INCLUDES ****************************************************************/
13
14#include <ntddk.h>
15#include "sndblst.h"
16
20
21/* INTERNAL VARIABLES ******************************************************/
22
24
25
26/* FUNCTIONS ***************************************************************/
27
31{
32// PDEVICE_INSTANCE Instance = Context;
33 PDEVICE_OBJECT DeviceObject; // = Context;
34 PDEVICE_EXTENSION Parameters; // = DeviceObject->DeviceExtension;
35 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\WaveOut0"); // CHANGE THESE?
36 UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\??\\WaveOut0");
37
38// CONFIG Config;
40 NTSTATUS s;
41 USHORT DSP_Version = 0;
42 UCHAR DSP_Major = 0, DSP_Minor = 0;
43
44 // This is TEMPORARY, to ensure that we don't process more than 1 device.
45 // This limitation should be removed in future.
46 if (DeviceCount > 0)
47 {
48 DPRINT("Sorry - only 1 device supported by Sound Blaster driver at present :(\n");
50 }
51
52 DPRINT("Creating IO device\n");
53
54 s = IoCreateDevice(Context, // driverobject
55 sizeof(DEVICE_EXTENSION),
57 FILE_DEVICE_SOUND, // Correct?
58 0,
59 FALSE,
61
62 if (!NT_SUCCESS(s))
63 return s;
64
65 DPRINT("Device Extension at 0x%x\n", DeviceObject->DeviceExtension);
66 Parameters = DeviceObject->DeviceExtension;
67
68 DPRINT("Creating DOS link\n");
69
70 /* Create the dos device link */
71 s = IoCreateSymbolicLink(&SymlinkName,
72 &DeviceName);
73
74 if (!NT_SUCCESS(s))
75 {
77 return s;
78 }
79
80 DPRINT("Initializing device\n");
81
82// DPRINT("Allocating memory for parameters structure\n");
83 // Bodged:
84// Parameters = (PDEVICE_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(DEVICE_EXTENSION));
85// DeviceObject->DeviceExtension = Parameters;
86// Parameters = Instance->DriverObject->DriverExtension;
87
88 DPRINT("DeviceObject at 0x%x, DeviceExtension at 0x%x\n", DeviceObject, Parameters);
89
90 if (! Parameters)
91 {
92 DPRINT("NULL POINTER!\n");
94 }
95
96// Instance->DriverObject->DriverExtension = Parameters;
97
98 DPRINT("Setting reg path\n");
99 Parameters->RegistryPath = RegistryPath;
100// Parameters->DriverObject = Instance->DriverObject;
101
102 DPRINT("Zeroing table memory and setting query routine\n");
103 RtlZeroMemory(Table, sizeof(Table));
104 Table[0].QueryRoutine = LoadSettings;
105
106 DPRINT("Setting port and IRQ defaults\n");
107 Parameters->Port = DEFAULT_PORT;
108 Parameters->IRQ = DEFAULT_IRQ;
109 Parameters->DMA = DEFAULT_DMA;
110 Parameters->BufferSize = DEFAULT_BUFSIZE;
111
112// Only to be enabled once we can get support for multiple cards working :)
113/*
114 DPRINT("Loading settings from: %S\n", RegistryPath);
115
116 s = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, RegistryPath, Table,
117 &Parameters, NULL);
118
119 if (! NT_SUCCESS(s))
120 return s;
121*/
122
123 DPRINT("Port 0x%x IRQ %d DMA %d\n", Parameters->Port, Parameters->IRQ, Parameters->DMA);
124
125// Instance->P
126
127 // Initialize the card
128 DSP_Version = InitSoundCard(Parameters->Port);
129 if (! DSP_Version)
130 {
131 DPRINT("Sound card initialization FAILED!\n");
132 // Set state indication somehow
133 // Failure - what error code do we give?!
134 // return STATUS_????
136 return STATUS_UNSUCCESSFUL;
137 }
138
139 DSP_Major = DSP_Version / 256;
140 DSP_Minor = DSP_Version % 256;
141
142 // Do stuff related to version here...
143
144 DPRINT("Allocating DMA\n");
145 if (! CreateDMA(DeviceObject))
146 DPRINT("FAILURE!\n");
147
148 // TEMPORARY TESTING STUFF: should be in BlasterCreate
150 SetOutputSampleRate(Parameters->Port, 2205);
151 BeginPlayback(Parameters->Port, 16, 2, Parameters->BufferSize);
152
153 DeviceCount ++;
154
155 return STATUS_SUCCESS;
156}
157
158
159static NTSTATUS NTAPI
161 PIRP Irp)
162/*
163 * FUNCTION: Handles user mode requests
164 * ARGUMENTS:
165 * DeviceObject = Device for request
166 * Irp = I/O request packet describing request
167 * RETURNS: Success or failure
168 */
169{
170 DPRINT("BlasterCreate() called!\n");
171
172 // Initialize the MPU-401
173 // ... do stuff ...
174
175
176 // Play a note to say we're alive:
177// WaitToSend(MPU401_PORT);
178// MPU401_WRITE_DATA(MPU401_PORT, 0x90);
179// WaitToSend(MPU401_PORT);
180// MPU401_WRITE_DATA(MPU401_PORT, 0x50);
181// WaitToSend(MPU401_PORT);
182// MPU401_WRITE_DATA(MPU401_PORT, 0x7f);
183
184 Irp->IoStatus.Status = STATUS_SUCCESS;
185 Irp->IoStatus.Information = 0;
186
187 DPRINT("IoCompleteRequest()\n");
188
191
192 DPRINT("BlasterCreate() completed\n");
193
194 return(STATUS_SUCCESS);
195}
196
197
198static NTSTATUS NTAPI
200 PIRP Irp)
201/*
202 * FUNCTION: Handles user mode requests
203 * ARGUMENTS:
204 * DeviceObject = Device for request
205 * Irp = I/O request packet describing request
206 * RETURNS: Success or failure
207 */
208{
209 PDEVICE_EXTENSION DeviceExtension;
211
212 DPRINT("BlasterClose() called!\n");
213
214 DeviceExtension = DeviceObject->DeviceExtension;
215
217
218 Irp->IoStatus.Status = Status;
219 Irp->IoStatus.Information = 0;
222
223 return(Status);
224}
225
226
227static NTSTATUS NTAPI
229 PIRP Irp)
230/*
231 * FUNCTION: Handles user mode requests
232 * ARGUMENTS:
233 * DeviceObject = Device for request
234 * Irp = I/O request packet describing request
235 * RETURNS: Success or failure
236 */
237{
238 ULONG Channel;
239 DPRINT("BlasterCleanup() called!\n");
240
241 // Reset the device (should we do this?)
242 for (Channel = 0; Channel <= 15; Channel ++)
243 {
244 // All notes off
245// MPU401_WRITE_MESSAGE(MPU401_PORT, 0xb0 + Channel, 123, 0);
246 // All controllers off
247// MPU401_WRITE_MESSAGE(MPU401_PORT, 0xb0 + Channel, 121, 0);
248 }
249
250
251 Irp->IoStatus.Status = STATUS_SUCCESS;
252 Irp->IoStatus.Information = 0;
255
256 return(STATUS_SUCCESS);
257}
258
259
260static NTSTATUS NTAPI
262{
264 PDEVICE_EXTENSION DeviceExtension;
266 PUCHAR Data;
267
268 DPRINT("BlasterWrite() called!\n");
269
270 DeviceExtension = DeviceObject->DeviceExtension;
272
273 DPRINT("%d bytes\n", Stack->Parameters.Write.Length);
274
275 Data = (PUCHAR) Irp->AssociatedIrp.SystemBuffer;
276
277 for (ByteCount = 0; ByteCount < Stack->Parameters.Write.Length; ByteCount ++)
278 {
279// DPRINT("0x%x ", Data[ByteCount]);
280
281// MPU401_WRITE_BYTE(DeviceExtension->Port, Data[ByteCount]);
282 }
283
284 Irp->IoStatus.Status = STATUS_SUCCESS;
285 Irp->IoStatus.Information = 0;
288
289 return(STATUS_SUCCESS);
290}
291
292
293static NTSTATUS NTAPI
295 PIRP Irp)
296/*
297 * FUNCTION: Handles user mode requests
298 * ARGUMENTS:
299 * DeviceObject = Device for request
300 * Irp = I/O request packet describing request
301 * RETURNS: Success or failure
302 */
303{
305 PDEVICE_EXTENSION DeviceExtension;
306
307 DPRINT("BlasterDeviceControl() called!\n");
308
309 DeviceExtension = DeviceObject->DeviceExtension;
311
312 switch(Stack->Parameters.DeviceIoControl.IoControlCode)
313 {
314/* case IOCTL_MIDI_PLAY :
315 {
316 DPRINT("Received IOCTL_MIDI_PLAY\n");
317 Data = (PUCHAR) Irp->AssociatedIrp.SystemBuffer;
318
319 DPRINT("Sending %d bytes of MIDI data to 0x%x:\n", Stack->Parameters.DeviceIoControl.InputBufferLength, DeviceExtension->Port);
320
321 for (ByteCount = 0; ByteCount < Stack->Parameters.DeviceIoControl.InputBufferLength; ByteCount ++)
322 {
323 DPRINT("0x%x ", Data[ByteCount]);
324
325 MPU401_WRITE_BYTE(DeviceExtension->Port, Data[ByteCount]);
326// if (WaitToSend(MPU401_PORT))
327// MPU401_WRITE_DATA(MPU401_PORT, Data[ByteCount]);
328 }
329
330 Irp->IoStatus.Status = STATUS_SUCCESS;
331 IoCompleteRequest(Irp, IO_NO_INCREMENT);
332
333 return(STATUS_SUCCESS);
334 }
335*/
336 }
337
338 return(STATUS_SUCCESS);
339
340/*
341 DeviceExtension = DeviceObject->DeviceExtension;
342 Stack = IoGetCurrentIrpStackLocation(Irp);
343 BeepParam = (PBEEP_SET_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
344
345 Irp->IoStatus.Information = 0;
346
347 if (Stack->Parameters.DeviceIoControl.IoControlCode != IOCTL_BEEP_SET)
348 {
349 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
350 IoCompleteRequest(Irp,
351 IO_NO_INCREMENT);
352 return(STATUS_NOT_IMPLEMENTED);
353 }
354
355 if ((Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(BEEP_SET_PARAMETERS))
356 || (BeepParam->Frequency < BEEP_FREQUENCY_MINIMUM)
357 || (BeepParam->Frequency > BEEP_FREQUENCY_MAXIMUM))
358 {
359 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
360 IoCompleteRequest(Irp,
361 IO_NO_INCREMENT);
362 return(STATUS_INVALID_PARAMETER);
363 }
364
365 DueTime.QuadPart = 0;
366*/
367 /* do the beep!! */
368/* DPRINT("Beep:\n Freq: %lu Hz\n Dur: %lu ms\n",
369 pbsp->Frequency,
370 pbsp->Duration);
371
372 if (BeepParam->Duration >= 0)
373 {
374 DueTime.QuadPart = (LONGLONG)BeepParam->Duration * -10000;
375
376 KeSetTimer(&DeviceExtension->Timer,
377 DueTime,
378 &DeviceExtension->Dpc);
379
380 HalMakeBeep(BeepParam->Frequency);
381 DeviceExtension->BeepOn = TRUE;
382 KeWaitForSingleObject(&DeviceExtension->Event,
383 Executive,
384 KernelMode,
385 FALSE,
386 NULL);
387 }
388 else if (BeepParam->Duration == (DWORD)-1)
389 {
390 if (DeviceExtension->BeepOn != FALSE)
391 {
392 HalMakeBeep(0);
393 DeviceExtension->BeepOn = FALSE;
394 }
395 else
396 {
397 HalMakeBeep(BeepParam->Frequency);
398 DeviceExtension->BeepOn = TRUE;
399 }
400 }
401
402 DPRINT("Did the beep!\n");
403
404 Irp->IoStatus.Status = STATUS_SUCCESS;
405 IoCompleteRequest(Irp,
406 IO_NO_INCREMENT);
407 return(STATUS_SUCCESS);
408*/
409}
410
411
412static VOID NTAPI
414{
415 DPRINT("BlasterUnload() called!\n");
416}
417
418
422/*
423 * FUNCTION: Called by the system to initialize the driver
424 * ARGUMENTS:
425 * DriverObject = object describing this driver
426 * RegistryPath = path to our configuration entries
427 * RETURNS: Success or failure
428 */
429{
430// PDEVICE_EXTENSION DeviceExtension;
431// PDEVICE_OBJECT DeviceObject;
432// DEVICE_INSTANCE Instance;
433 // Doesn't support multiple instances (yet ...)
435
436 DPRINT("Sound Blaster Device Driver 0.0.2\n");
437
438// Instance.DriverObject = DriverObject;
439 // previous instance = NULL...
440
441// DeviceExtension->RegistryPath = RegistryPath;
442
443 DriverObject->Flags = 0;
444 DriverObject->MajorFunction[IRP_MJ_CREATE] = BlasterCreate;
445 DriverObject->MajorFunction[IRP_MJ_CLOSE] = BlasterClose;
448 DriverObject->MajorFunction[IRP_MJ_WRITE] = BlasterWrite;
449 DriverObject->DriverUnload = BlasterUnload;
450
451 // Major hack to just get this damn thing working:
452 Status = InitDevice(RegistryPath->Buffer, DriverObject); // ????
453
454// DPRINT("Enumerating devices at %wZ\n", RegistryPath);
455
456// Status = EnumDeviceKeys(RegistryPath, PARMS_SUBKEY, InitDevice, (PVOID)&DeviceObject); // &Instance;
457
458 // check error
459
460 /* set up device extension */
461// DeviceExtension = DeviceObject->DeviceExtension;
462// DeviceExtension->BeepOn = FALSE;
463
464// return(STATUS_SUCCESS);
465 return(Status);
466}
467
468/* EOF */
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
void LoadSettings(void)
Definition: settings.c:53
LONG NTSTATUS
Definition: precomp.h:26
VOID BeginPlayback(ULONG BasePort, ULONG BitDepth, ULONG Channels, ULONG BlockSize)
Definition: card.c:51
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
BOOLEAN SetOutputSampleRate(PSOUND_BLASTER_PARAMETERS SBDevice, ULONG SampleRate)
Definition: control.c:143
BOOLEAN EnableSpeaker(PSOUND_BLASTER_PARAMETERS SBDevice)
Definition: control.c:158
BOOLEAN CreateDMA(PDEVICE_OBJECT DeviceObject)
Definition: dma.c:70
USHORT InitSoundCard(ULONG BasePort)
Definition: portio.c:62
static NTSTATUS NTAPI BlasterCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: sndblst.c:160
static NTSTATUS NTAPI BlasterClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: sndblst.c:199
static NTSTATUS NTAPI BlasterDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: sndblst.c:294
static NTSTATUS NTAPI BlasterCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: sndblst.c:228
static VOID NTAPI BlasterUnload(PDRIVER_OBJECT DriverObject)
Definition: sndblst.c:413
static NTSTATUS NTAPI BlasterWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: sndblst.c:261
ULONG DeviceCount
Definition: sndblst.c:23
static NTSTATUS InitDevice(IN PWSTR RegistryPath, IN PVOID Context)
Definition: sndblst.c:28
Status
Definition: gdiplustypes.h:25
ASMGENDATA Table[]
Definition: genincdata.c:61
GLdouble s
Definition: gl.h:2039
#define for
Definition: utility.h:88
#define DEFAULT_PORT
Definition: mpu401.h:19
#define DEFAULT_IRQ
Definition: mpu401.h:20
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
#define FILE_DEVICE_SOUND
Definition: winioctl.h:135
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define DEFAULT_DMA
Definition: sndblst.h:14
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DEFAULT_BUFSIZE
Definition: sndblst.h:22
#define DPRINT
Definition: sndvol32.h:73
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
uint16_t * PWSTR
Definition: typedefs.h:56
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
#define IO_NO_INCREMENT
Definition: iotypes.h:598
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1099
#define IRP_MJ_CLEANUP
unsigned char UCHAR
Definition: xmlstorage.h:181