ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

sndblst.c
Go to the documentation of this file.
00001 /*
00002  *
00003  * COPYRIGHT:            See COPYING in the top level directory
00004  * PROJECT:              ReactOS kernel
00005  * FILE:                 services/dd/sndblst/sndblst.c
00006  * PURPOSE:              Sound Blaster / SB Pro / SB 16 driver
00007  * PROGRAMMER:           Andrew Greenwood
00008  * UPDATE HISTORY:
00009  *                       Sept 28, 2003: Copied from mpu401.c as a template
00010  */
00011 
00012 /* INCLUDES ****************************************************************/
00013 
00014 #include <ntddk.h>
00015 #include "sndblst.h"
00016 
00017 NTSTATUS NTAPI
00018 DriverEntry(PDRIVER_OBJECT DriverObject,
00019         PUNICODE_STRING RegistryPath);
00020 
00021 /* INTERNAL VARIABLES ******************************************************/
00022 
00023 ULONG DeviceCount = 0;
00024 
00025 
00026 /* FUNCTIONS ***************************************************************/
00027 
00028 static NTSTATUS InitDevice(
00029     IN PWSTR RegistryPath,
00030     IN PVOID Context)
00031 {
00032 //    PDEVICE_INSTANCE Instance = Context;
00033     PDEVICE_OBJECT DeviceObject; // = Context;
00034     PDEVICE_EXTENSION Parameters; // = DeviceObject->DeviceExtension;
00035     UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\WaveOut0");   // CHANGE THESE?
00036     UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\??\\WaveOut0");
00037 
00038 //    CONFIG Config;
00039     RTL_QUERY_REGISTRY_TABLE Table[2];
00040     NTSTATUS s;
00041     USHORT DSP_Version = 0;
00042     UCHAR DSP_Major = 0, DSP_Minor = 0;
00043 
00044     // This is TEMPORARY, to ensure that we don't process more than 1 device.
00045     // This limitation should be removed in future.
00046     if (DeviceCount > 0)
00047     {
00048         DPRINT("Sorry - only 1 device supported by Sound Blaster driver at present :(\n");
00049         return STATUS_NOT_IMPLEMENTED;
00050     }
00051 
00052     DPRINT("Creating IO device\n");
00053 
00054     s = IoCreateDevice(Context, // driverobject
00055               sizeof(DEVICE_EXTENSION),
00056               &DeviceName,
00057               FILE_DEVICE_SOUND, // Correct?
00058               0,
00059               FALSE,
00060               &DeviceObject);
00061 
00062     if (!NT_SUCCESS(s))
00063         return s;
00064 
00065     DPRINT("Device Extension at 0x%x\n", DeviceObject->DeviceExtension);
00066     Parameters = DeviceObject->DeviceExtension;
00067 
00068     DPRINT("Creating DOS link\n");
00069 
00070     /* Create the dos device link */
00071     s = IoCreateSymbolicLink(&SymlinkName,
00072                &DeviceName);
00073 
00074     if (!NT_SUCCESS(s))
00075     {
00076         IoDeleteDevice(DeviceObject);
00077         return s;
00078     }
00079 
00080     DPRINT("Initializing device\n");
00081 
00082 //    DPRINT("Allocating memory for parameters structure\n");
00083     // Bodged:
00084 //    Parameters = (PDEVICE_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(DEVICE_EXTENSION));
00085 //    DeviceObject->DeviceExtension = Parameters;
00086 //    Parameters = Instance->DriverObject->DriverExtension;
00087 
00088     DPRINT("DeviceObject at 0x%x, DeviceExtension at 0x%x\n", DeviceObject, Parameters);
00089 
00090     if (! Parameters)
00091     {
00092         DPRINT("NULL POINTER!\n");
00093         return STATUS_INSUFFICIENT_RESOURCES;
00094     }
00095 
00096 //    Instance->DriverObject->DriverExtension = Parameters;
00097 
00098     DPRINT("Setting reg path\n");
00099     Parameters->RegistryPath = RegistryPath;
00100 //    Parameters->DriverObject = Instance->DriverObject;
00101 
00102     DPRINT("Zeroing table memory and setting query routine\n");
00103     RtlZeroMemory(Table, sizeof(Table));
00104     Table[0].QueryRoutine = LoadSettings;
00105 
00106     DPRINT("Setting port and IRQ defaults\n");
00107     Parameters->Port = DEFAULT_PORT;
00108     Parameters->IRQ = DEFAULT_IRQ;
00109     Parameters->DMA = DEFAULT_DMA;
00110     Parameters->BufferSize = DEFAULT_BUFSIZE;
00111 
00112 // Only to be enabled once we can get support for multiple cards working :)
00113 /*
00114     DPRINT("Loading settings from: %S\n", RegistryPath);
00115 
00116     s = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, RegistryPath, Table,
00117                                 &Parameters, NULL);
00118 
00119     if (! NT_SUCCESS(s))
00120         return s;
00121 */
00122 
00123     DPRINT("Port 0x%x  IRQ %d  DMA %d\n", Parameters->Port, Parameters->IRQ, Parameters->DMA);
00124 
00125 //    Instance->P
00126 
00127     // Initialize the card
00128     DSP_Version = InitSoundCard(Parameters->Port);
00129     if (! DSP_Version)
00130     {
00131         DPRINT("Sound card initialization FAILED!\n");
00132         // Set state indication somehow
00133         // Failure - what error code do we give?!
00134         // return STATUS_????
00135         IoDeleteDevice(DeviceObject);
00136         return STATUS_UNSUCCESSFUL;
00137     }
00138 
00139     DSP_Major = DSP_Version / 256;
00140     DSP_Minor = DSP_Version % 256;
00141 
00142     // Do stuff related to version here...
00143 
00144     DPRINT("Allocating DMA\n");
00145     if (! CreateDMA(DeviceObject))
00146         DPRINT("FAILURE!\n");
00147 
00148     // TEMPORARY TESTING STUFF: should be in BlasterCreate
00149     EnableSpeaker(Parameters->Port, TRUE);
00150     SetOutputSampleRate(Parameters->Port, 2205);
00151     BeginPlayback(Parameters->Port, 16, 2, Parameters->BufferSize);
00152 
00153     DeviceCount ++;
00154 
00155     return STATUS_SUCCESS;
00156 }
00157 
00158 
00159 static NTSTATUS NTAPI
00160 BlasterCreate(PDEVICE_OBJECT DeviceObject,
00161        PIRP Irp)
00162 /*
00163  * FUNCTION: Handles user mode requests
00164  * ARGUMENTS:
00165  *                       DeviceObject = Device for request
00166  *                       Irp = I/O request packet describing request
00167  * RETURNS: Success or failure
00168  */
00169 {
00170     DPRINT("BlasterCreate() called!\n");
00171 
00172     // Initialize the MPU-401
00173     // ... do stuff ...
00174 
00175 
00176     // Play a note to say we're alive:
00177 //    WaitToSend(MPU401_PORT);
00178 //    MPU401_WRITE_DATA(MPU401_PORT, 0x90);
00179 //    WaitToSend(MPU401_PORT);
00180 //    MPU401_WRITE_DATA(MPU401_PORT, 0x50);
00181 //    WaitToSend(MPU401_PORT);
00182 //    MPU401_WRITE_DATA(MPU401_PORT, 0x7f);
00183 
00184     Irp->IoStatus.Status = STATUS_SUCCESS;
00185     Irp->IoStatus.Information = 0;
00186 
00187     DPRINT("IoCompleteRequest()\n");
00188 
00189     IoCompleteRequest(Irp,
00190             IO_NO_INCREMENT);
00191 
00192     DPRINT("BlasterCreate() completed\n");
00193 
00194     return(STATUS_SUCCESS);
00195 }
00196 
00197 
00198 static NTSTATUS NTAPI
00199 BlasterClose(PDEVICE_OBJECT DeviceObject,
00200       PIRP Irp)
00201 /*
00202  * FUNCTION: Handles user mode requests
00203  * ARGUMENTS:
00204  *                       DeviceObject = Device for request
00205  *                       Irp = I/O request packet describing request
00206  * RETURNS: Success or failure
00207  */
00208 {
00209   PDEVICE_EXTENSION DeviceExtension;
00210   NTSTATUS Status;
00211 
00212   DPRINT("BlasterClose() called!\n");
00213 
00214   DeviceExtension = DeviceObject->DeviceExtension;
00215 
00216   Status = STATUS_SUCCESS;
00217 
00218   Irp->IoStatus.Status = Status;
00219   Irp->IoStatus.Information = 0;
00220   IoCompleteRequest(Irp,
00221             IO_NO_INCREMENT);
00222 
00223   return(Status);
00224 }
00225 
00226 
00227 static NTSTATUS NTAPI
00228 BlasterCleanup(PDEVICE_OBJECT DeviceObject,
00229         PIRP Irp)
00230 /*
00231  * FUNCTION: Handles user mode requests
00232  * ARGUMENTS:
00233  *                       DeviceObject = Device for request
00234  *                       Irp = I/O request packet describing request
00235  * RETURNS: Success or failure
00236  */
00237 {
00238   ULONG Channel;
00239   DPRINT("BlasterCleanup() called!\n");
00240 
00241     // Reset the device (should we do this?)
00242     for (Channel = 0; Channel <= 15; Channel ++)
00243     {
00244         // All notes off
00245 //        MPU401_WRITE_MESSAGE(MPU401_PORT, 0xb0 + Channel, 123, 0);
00246         // All controllers off
00247 //        MPU401_WRITE_MESSAGE(MPU401_PORT, 0xb0 + Channel, 121, 0);
00248     }
00249 
00250 
00251   Irp->IoStatus.Status = STATUS_SUCCESS;
00252   Irp->IoStatus.Information = 0;
00253   IoCompleteRequest(Irp,
00254             IO_NO_INCREMENT);
00255 
00256   return(STATUS_SUCCESS);
00257 }
00258 
00259 
00260 static NTSTATUS NTAPI
00261 BlasterWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
00262 {
00263     PIO_STACK_LOCATION Stack;
00264     PDEVICE_EXTENSION DeviceExtension;
00265     ULONG ByteCount;
00266     PUCHAR Data;
00267 
00268     DPRINT("BlasterWrite() called!\n");
00269 
00270     DeviceExtension = DeviceObject->DeviceExtension;
00271     Stack = IoGetCurrentIrpStackLocation(Irp);
00272 
00273     DPRINT("%d bytes\n", Stack->Parameters.Write.Length);
00274 
00275             Data = (PUCHAR) Irp->AssociatedIrp.SystemBuffer;
00276 
00277             for (ByteCount = 0; ByteCount < Stack->Parameters.Write.Length; ByteCount ++)
00278             {
00279 //                DPRINT("0x%x ", Data[ByteCount]);
00280 
00281 //                MPU401_WRITE_BYTE(DeviceExtension->Port, Data[ByteCount]);
00282             }
00283 
00284   Irp->IoStatus.Status = STATUS_SUCCESS;
00285   Irp->IoStatus.Information = 0;
00286   IoCompleteRequest(Irp,
00287             IO_NO_INCREMENT);
00288 
00289   return(STATUS_SUCCESS);
00290 }
00291 
00292 
00293 static NTSTATUS NTAPI
00294 BlasterDeviceControl(PDEVICE_OBJECT DeviceObject,
00295           PIRP Irp)
00296 /*
00297  * FUNCTION: Handles user mode requests
00298  * ARGUMENTS:
00299  *                       DeviceObject = Device for request
00300  *                       Irp = I/O request packet describing request
00301  * RETURNS: Success or failure
00302  */
00303 {
00304     PIO_STACK_LOCATION Stack;
00305     PDEVICE_EXTENSION DeviceExtension;
00306 
00307     DPRINT("BlasterDeviceControl() called!\n");
00308 
00309     DeviceExtension = DeviceObject->DeviceExtension;
00310     Stack = IoGetCurrentIrpStackLocation(Irp);
00311 
00312     switch(Stack->Parameters.DeviceIoControl.IoControlCode)
00313     {
00314 /*        case IOCTL_MIDI_PLAY :
00315         {
00316             DPRINT("Received IOCTL_MIDI_PLAY\n");
00317             Data = (PUCHAR) Irp->AssociatedIrp.SystemBuffer;
00318 
00319             DPRINT("Sending %d bytes of MIDI data to 0x%d:\n", Stack->Parameters.DeviceIoControl.InputBufferLength, DeviceExtension->Port);
00320 
00321             for (ByteCount = 0; ByteCount < Stack->Parameters.DeviceIoControl.InputBufferLength; ByteCount ++)
00322             {
00323                 DPRINT("0x%x ", Data[ByteCount]);
00324 
00325                 MPU401_WRITE_BYTE(DeviceExtension->Port, Data[ByteCount]);
00326 //                if (WaitToSend(MPU401_PORT))
00327 //                    MPU401_WRITE_DATA(MPU401_PORT, Data[ByteCount]);
00328             }
00329 
00330             Irp->IoStatus.Status = STATUS_SUCCESS;
00331             IoCompleteRequest(Irp, IO_NO_INCREMENT);
00332 
00333             return(STATUS_SUCCESS);
00334         }
00335 */
00336     }
00337 
00338     return(STATUS_SUCCESS);
00339 
00340 /*
00341   DeviceExtension = DeviceObject->DeviceExtension;
00342   Stack = IoGetCurrentIrpStackLocation(Irp);
00343   BeepParam = (PBEEP_SET_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
00344 
00345   Irp->IoStatus.Information = 0;
00346 
00347   if (Stack->Parameters.DeviceIoControl.IoControlCode != IOCTL_BEEP_SET)
00348     {
00349       Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
00350       IoCompleteRequest(Irp,
00351             IO_NO_INCREMENT);
00352       return(STATUS_NOT_IMPLEMENTED);
00353     }
00354 
00355   if ((Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(BEEP_SET_PARAMETERS))
00356       || (BeepParam->Frequency < BEEP_FREQUENCY_MINIMUM)
00357       || (BeepParam->Frequency > BEEP_FREQUENCY_MAXIMUM))
00358     {
00359       Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
00360       IoCompleteRequest(Irp,
00361             IO_NO_INCREMENT);
00362       return(STATUS_INVALID_PARAMETER);
00363     }
00364 
00365   DueTime.QuadPart = 0;
00366 */
00367   /* do the beep!! */
00368 /*  DPRINT("Beep:\n  Freq: %lu Hz\n  Dur: %lu ms\n",
00369      pbsp->Frequency,
00370      pbsp->Duration);
00371 
00372   if (BeepParam->Duration >= 0)
00373     {
00374       DueTime.QuadPart = (LONGLONG)BeepParam->Duration * -10000;
00375 
00376       KeSetTimer(&DeviceExtension->Timer,
00377          DueTime,
00378          &DeviceExtension->Dpc);
00379 
00380       HalMakeBeep(BeepParam->Frequency);
00381       DeviceExtension->BeepOn = TRUE;
00382       KeWaitForSingleObject(&DeviceExtension->Event,
00383                 Executive,
00384                 KernelMode,
00385                 FALSE,
00386                 NULL);
00387     }
00388   else if (BeepParam->Duration == (DWORD)-1)
00389     {
00390       if (DeviceExtension->BeepOn == TRUE)
00391     {
00392       HalMakeBeep(0);
00393       DeviceExtension->BeepOn = FALSE;
00394     }
00395       else
00396     {
00397       HalMakeBeep(BeepParam->Frequency);
00398       DeviceExtension->BeepOn = TRUE;
00399     }
00400     }
00401 
00402   DPRINT("Did the beep!\n");
00403 
00404   Irp->IoStatus.Status = STATUS_SUCCESS;
00405   IoCompleteRequest(Irp,
00406             IO_NO_INCREMENT);
00407   return(STATUS_SUCCESS);
00408 */
00409 }
00410 
00411 
00412 static VOID NTAPI
00413 BlasterUnload(PDRIVER_OBJECT DriverObject)
00414 {
00415   DPRINT("BlasterUnload() called!\n");
00416 }
00417 
00418 
00419 NTSTATUS NTAPI
00420 DriverEntry(PDRIVER_OBJECT DriverObject,
00421         PUNICODE_STRING RegistryPath)
00422 /*
00423  * FUNCTION:  Called by the system to initalize the driver
00424  * ARGUMENTS:
00425  *            DriverObject = object describing this driver
00426  *            RegistryPath = path to our configuration entries
00427  * RETURNS:   Success or failure
00428  */
00429 {
00430 //  PDEVICE_EXTENSION DeviceExtension;
00431 //  PDEVICE_OBJECT DeviceObject;
00432 //  DEVICE_INSTANCE Instance;
00433   // Doesn't support multiple instances (yet ...)
00434   NTSTATUS Status;
00435 
00436   DPRINT("Sound Blaster Device Driver 0.0.2\n");
00437 
00438 //    Instance.DriverObject = DriverObject;
00439     // previous instance = NULL...
00440 
00441 //    DeviceExtension->RegistryPath = RegistryPath;
00442 
00443   DriverObject->Flags = 0;
00444   DriverObject->MajorFunction[IRP_MJ_CREATE] = BlasterCreate;
00445   DriverObject->MajorFunction[IRP_MJ_CLOSE] = BlasterClose;
00446   DriverObject->MajorFunction[IRP_MJ_CLEANUP] = BlasterCleanup;
00447   DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = BlasterDeviceControl;
00448   DriverObject->MajorFunction[IRP_MJ_WRITE] = BlasterWrite;
00449   DriverObject->DriverUnload = BlasterUnload;
00450 
00451     // Major hack to just get this damn thing working:
00452     Status = InitDevice(RegistryPath->Buffer, DriverObject);    // ????
00453 
00454 //    DPRINT("Enumerating devices at %wZ\n", RegistryPath);
00455 
00456 //    Status = EnumDeviceKeys(RegistryPath, PARMS_SUBKEY, InitDevice, (PVOID)&DeviceObject); // &Instance;
00457 
00458     // check error
00459 
00460   /* set up device extension */
00461 //  DeviceExtension = DeviceObject->DeviceExtension;
00462 //  DeviceExtension->BeepOn = FALSE;
00463 
00464 //  return(STATUS_SUCCESS);
00465     return(Status);
00466 }
00467 
00468 /* EOF */

Generated on Fri May 25 2012 04:24:39 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.