ReactOS  0.4.14-dev-115-g4576127
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),
56  &DeviceName,
57  FILE_DEVICE_SOUND, // Correct?
58  0,
59  FALSE,
60  &DeviceObject);
61 
62  if (!NT_SUCCESS(s))
63  return s;
64 
65  DPRINT("Device Extension at 0x%x\n", 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
149  EnableSpeaker(Parameters->Port, TRUE);
150  SetOutputSampleRate(Parameters->Port, 2205);
151  BeginPlayback(Parameters->Port, 16, 2, Parameters->BufferSize);
152 
153  DeviceCount ++;
154 
155  return STATUS_SUCCESS;
156 }
157 
158 
159 static 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 
198 static 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 
227 static 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 
260 static NTSTATUS NTAPI
262 {
263  PIO_STACK_LOCATION Stack;
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 
293 static 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 {
304  PIO_STACK_LOCATION Stack;
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 
412 static 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;
450 
451  // Major hack to just get this damn thing working:
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 NTSTATUS NTAPI BlasterWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: sndblst.c:261
#define IN
Definition: typedefs.h:38
ASMGENDATA Table[]
Definition: genincdata.c:61
#define TRUE
Definition: types.h:120
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define DEFAULT_PORT
Definition: mpu401.h:19
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static NTSTATUS NTAPI BlasterCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: sndblst.c:228
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
_In_ PIRP Irp
Definition: csq.h:116
uint16_t * PWSTR
Definition: typedefs.h:54
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
static NTSTATUS NTAPI BlasterClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: sndblst.c:199
NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
Definition: sndblst.c:420
static NTSTATUS NTAPI BlasterCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: sndblst.c:160
WCHAR DeviceName[]
Definition: adapter.cpp:21
static NTSTATUS InitDevice(IN PWSTR RegistryPath, IN PVOID Context)
Definition: sndblst.c:28
BOOLEAN CreateDMA(PDEVICE_OBJECT DeviceObject)
Definition: dma.c:70
void LoadSettings(void)
Definition: settings.c:53
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define DEFAULT_DMA
Definition: sndblst.h:14
PVOID DeviceExtension
Definition: env_spec_w32.h:418
BOOLEAN SetOutputSampleRate(PSOUND_BLASTER_PARAMETERS SBDevice, ULONG SampleRate)
Definition: control.c:143
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
void DPRINT(...)
Definition: polytest.cpp:61
#define DEFAULT_BUFSIZE
Definition: sndblst.h:22
static VOID NTAPI BlasterUnload(PDRIVER_OBJECT DriverObject)
Definition: sndblst.c:413
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define for
Definition: utility.h:88
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:872
static const WCHAR L[]
Definition: oid.c:1250
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2180
static NTSTATUS NTAPI BlasterDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: sndblst.c:294
GLdouble s
Definition: gl.h:2039
#define FILE_DEVICE_SOUND
Definition: winioctl.h:134
USHORT InitSoundCard(ULONG BasePort)
Definition: portio.c:62
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1061
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
BOOLEAN EnableSpeaker(PSOUND_BLASTER_PARAMETERS SBDevice)
Definition: control.c:158
unsigned short USHORT
Definition: pedump.c:61
#define DEFAULT_IRQ
Definition: mpu401.h:20
ULONG DeviceCount
Definition: sndblst.c:23
#define IRP_MJ_CLEANUP
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
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
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2966
VOID BeginPlayback(ULONG BasePort, ULONG BitDepth, ULONG Channels, ULONG BlockSize)
Definition: card.c:51
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14