⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpu401.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
字号:
/* * * COPYRIGHT:            See COPYING in the top level directory * PROJECT:              ReactOS kernel * FILE:                 services/dd/mpu401/mpu401.c * PURPOSE:              MPU-401 MIDI device driver * PROGRAMMER:           Andrew Greenwood * UPDATE HISTORY: *                       Sept 26, 2003: Copied from beep.c as template *                       Sept 27, 2003: Implemented MPU-401 init & playback *//* INCLUDES ****************************************************************/#include <ntddk.h>//#include <ntddbeep.h>//#define NDEBUG#include <debug.h>#include "mpu401.h"/* INTERNAL VARIABLES ******************************************************/ULONG DeviceCount = 0;/* FUNCTIONS ***************************************************************/static NTSTATUS InitDevice(    IN PUNICODE_STRING RegistryPath,    IN PVOID Context){//    PDEVICE_INSTANCE Instance = Context;    PDEVICE_OBJECT DeviceObject; // = Context;    PDEVICE_EXTENSION Parameters; // = DeviceObject->DeviceExtension;    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MidiOut0");    UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\??\\MidiOut0");//    CONFIG Config;    RTL_QUERY_REGISTRY_TABLE Table[2];    NTSTATUS s;    // This is TEMPORARY, to ensure that we don't process more than 1 device.    // I'll remove this limitation in the future.    if (DeviceCount > 0)    {        DPRINT("Sorry - only 1 device supported by MPU401 driver at present :(\n");        return STATUS_NOT_IMPLEMENTED;    }    DPRINT("Creating IO device\n");    s = IoCreateDevice(Context, // driverobject			  sizeof(DEVICE_EXTENSION),			  &DeviceName,			  FILE_DEVICE_SOUND, // Correct?			  0,			  FALSE,			  &DeviceObject);    if (!NT_SUCCESS(s))        return s;    DPRINT("Device Extension at 0x%x\n", DeviceObject->DeviceExtension);    Parameters = DeviceObject->DeviceExtension;    DPRINT("Creating DOS link\n");    /* Create the dos device link */    IoCreateSymbolicLink(&SymlinkName,		       &DeviceName);    DPRINT("Initializing device\n");//    DPRINT("Allocating memory for parameters structure\n");    // Bodged://    Parameters = (PDEVICE_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(DEVICE_EXTENSION));//    DeviceObject->DeviceExtension = Parameters;//    Parameters = Instance->DriverObject->DriverExtension;    DPRINT("DeviceObject at 0x%x, DeviceExtension at 0x%x\n", DeviceObject, Parameters);    if (! Parameters)    {        DPRINT("NULL POINTER!\n");        return STATUS_INSUFFICIENT_RESOURCES;    }//    Instance->DriverObject->DriverExtension = Parameters;    DPRINT("Setting reg path\n");    Parameters->RegistryPath = RegistryPath;//    Parameters->DriverObject = Instance->DriverObject;    DPRINT("Zeroing table memory and setting query routine\n");    RtlZeroMemory(Table, sizeof(Table));    Table[0].QueryRoutine = LoadSettings;    DPRINT("Setting port and IRQ defaults\n");    Parameters->Port = DEFAULT_PORT;    Parameters->IRQ = DEFAULT_IRQ;// Only to be enabled once we can get support for multiple cards working :)/*    DPRINT("Loading settings from: %S\n", RegistryPath);    s = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, RegistryPath, Table,                                &Parameters, NULL);*/    if (! NT_SUCCESS(s))        return s;    DPRINT("Port 0x%x  IRQ %d\n", Parameters->Port, Parameters->IRQ);//    Instance->P    // Enter UART mode (should be done in init phase    if (! InitUARTMode(Parameters->Port))    {        DPRINT("UART mode initialization FAILED!\n");        // Set state indication somehow        // Failure - what error code do we give?!        // return STATUS_????    }    DeviceCount ++;    return STATUS_SUCCESS;}static NTSTATUS STDCALLMPU401Create(PDEVICE_OBJECT DeviceObject,	   PIRP Irp)/* * FUNCTION: Handles user mode requests * ARGUMENTS: *                       DeviceObject = Device for request *                       Irp = I/O request packet describing request * RETURNS: Success or failure */{    DPRINT("MPU401Create() called!\n");    // Initialize the MPU-401?    // ... do stuff ...    // Play a note to say we're alive:    WaitToSend(MPU401_PORT);    MPU401_WRITE_DATA(MPU401_PORT, 0x90);    WaitToSend(MPU401_PORT);    MPU401_WRITE_DATA(MPU401_PORT, 0x50);    WaitToSend(MPU401_PORT);    MPU401_WRITE_DATA(MPU401_PORT, 0x7f);    Irp->IoStatus.Status = STATUS_SUCCESS;    Irp->IoStatus.Information = 0;    IoCompleteRequest(Irp,		    IO_NO_INCREMENT);    return(STATUS_SUCCESS);}static NTSTATUS STDCALLMPU401Close(PDEVICE_OBJECT DeviceObject,	  PIRP Irp)/* * FUNCTION: Handles user mode requests * ARGUMENTS: *                       DeviceObject = Device for request *                       Irp = I/O request packet describing request * RETURNS: Success or failure */{  PDEVICE_EXTENSION DeviceExtension;  NTSTATUS Status;  DPRINT("MPU401Close() called!\n");  DeviceExtension = DeviceObject->DeviceExtension;  Status = STATUS_SUCCESS;  Irp->IoStatus.Status = Status;  Irp->IoStatus.Information = 0;  IoCompleteRequest(Irp,		    IO_NO_INCREMENT);  return(Status);}static NTSTATUS STDCALLMPU401Cleanup(PDEVICE_OBJECT DeviceObject,	    PIRP Irp)/* * FUNCTION: Handles user mode requests * ARGUMENTS: *                       DeviceObject = Device for request *                       Irp = I/O request packet describing request * RETURNS: Success or failure */{  ULONG Channel;  DPRINT("MPU401Cleanup() called!\n");    // Reset the device (should we do this?)    for (Channel = 0; Channel <= 15; Channel ++)    {        // All notes off//        MPU401_WRITE_MESSAGE(MPU401_PORT, 0xb0 + Channel, 123, 0);        // All controllers off//        MPU401_WRITE_MESSAGE(MPU401_PORT, 0xb0 + Channel, 121, 0);    }  Irp->IoStatus.Status = STATUS_SUCCESS;  Irp->IoStatus.Information = 0;  IoCompleteRequest(Irp,		    IO_NO_INCREMENT);  return(STATUS_SUCCESS);}static NTSTATUS STDCALLMPU401DeviceControl(PDEVICE_OBJECT DeviceObject,		  PIRP Irp)/* * FUNCTION: Handles user mode requests * ARGUMENTS: *                       DeviceObject = Device for request *                       Irp = I/O request packet describing request * RETURNS: Success or failure */{    PIO_STACK_LOCATION Stack;    PDEVICE_EXTENSION DeviceExtension;    ULONG ByteCount;    PUCHAR Data;    DPRINT("MPU401DeviceControl() called!\n");    DeviceExtension = DeviceObject->DeviceExtension;    Stack = IoGetCurrentIrpStackLocation(Irp);    DPRINT("Control code %d [0x%x]\n", Stack->Parameters.DeviceIoControl.IoControlCode,                Stack->Parameters.DeviceIoControl.IoControlCode);    switch(Stack->Parameters.DeviceIoControl.IoControlCode)    {        case IOCTL_MIDI_PLAY :        {            DPRINT("Received IOCTL_MIDI_PLAY\n");            Data = (PUCHAR) Irp->AssociatedIrp.SystemBuffer;            DPRINT("Sending %d bytes of MIDI data to 0x%d:\n", Stack->Parameters.DeviceIoControl.InputBufferLength, DeviceExtension->Port);            for (ByteCount = 0; ByteCount < Stack->Parameters.DeviceIoControl.InputBufferLength; ByteCount ++)            {                DPRINT("0x%x ", Data[ByteCount]);                MPU401_WRITE_BYTE(DeviceExtension->Port, Data[ByteCount]);//                if (WaitToSend(MPU401_PORT))//                    MPU401_WRITE_DATA(MPU401_PORT, Data[ByteCount]);            }            Irp->IoStatus.Status = STATUS_SUCCESS;            IoCompleteRequest(Irp, IO_NO_INCREMENT);            return(STATUS_SUCCESS);        }    }    return(STATUS_SUCCESS);/*  DeviceExtension = DeviceObject->DeviceExtension;  Stack = IoGetCurrentIrpStackLocation(Irp);  BeepParam = (PBEEP_SET_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;  Irp->IoStatus.Information = 0;  if (Stack->Parameters.DeviceIoControl.IoControlCode != IOCTL_BEEP_SET)    {      Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;      IoCompleteRequest(Irp,			IO_NO_INCREMENT);      return(STATUS_NOT_IMPLEMENTED);    }  if ((Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(BEEP_SET_PARAMETERS))      || (BeepParam->Frequency < BEEP_FREQUENCY_MINIMUM)      || (BeepParam->Frequency > BEEP_FREQUENCY_MAXIMUM))    {      Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;      IoCompleteRequest(Irp,			IO_NO_INCREMENT);      return(STATUS_INVALID_PARAMETER);    }  DueTime.QuadPart = 0;*/  /* do the beep!! *//*  DPRINT("Beep:\n  Freq: %lu Hz\n  Dur: %lu ms\n",	 pbsp->Frequency,	 pbsp->Duration);  if (BeepParam->Duration >= 0)    {      DueTime.QuadPart = (LONGLONG)BeepParam->Duration * -10000;      KeSetTimer(&DeviceExtension->Timer,		 DueTime,		 &DeviceExtension->Dpc);      HalMakeBeep(BeepParam->Frequency);      DeviceExtension->BeepOn = TRUE;      KeWaitForSingleObject(&DeviceExtension->Event,			    Executive,			    KernelMode,			    FALSE,			    NULL);    }  else if (BeepParam->Duration == (DWORD)-1)    {      if (DeviceExtension->BeepOn == TRUE)	{	  HalMakeBeep(0);	  DeviceExtension->BeepOn = FALSE;	}      else	{	  HalMakeBeep(BeepParam->Frequency);	  DeviceExtension->BeepOn = TRUE;	}    }  DPRINT("Did the beep!\n");  Irp->IoStatus.Status = STATUS_SUCCESS;  IoCompleteRequest(Irp,		    IO_NO_INCREMENT);  return(STATUS_SUCCESS);*/}static VOID STDCALLMPU401Unload(PDRIVER_OBJECT DriverObject){  DPRINT("MPU401Unload() called!\n");}NTSTATUS STDCALLDriverEntry(PDRIVER_OBJECT DriverObject,	    PUNICODE_STRING RegistryPath)/* * FUNCTION:  Called by the system to initalize the driver * ARGUMENTS: *            DriverObject = object describing this driver *            RegistryPath = path to our configuration entries * RETURNS:   Success or failure */{//  PDEVICE_EXTENSION DeviceExtension;//  PDEVICE_OBJECT DeviceObject;//  DEVICE_INSTANCE Instance;  // Doesn't support multiple instances (yet ...)  NTSTATUS Status;  DPRINT("MPU401 Device Driver 0.0.1\n");    // Is this really necessary? Yes! (Talking to myself again...)//    Instance.DriverObject = DriverObject;    // previous instance = NULL...//    DeviceExtension->RegistryPath = RegistryPath;  DriverObject->Flags = 0;  DriverObject->MajorFunction[IRP_MJ_CREATE] = MPU401Create;  DriverObject->MajorFunction[IRP_MJ_CLOSE] = MPU401Close;  DriverObject->MajorFunction[IRP_MJ_CLEANUP] = MPU401Cleanup;  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MPU401DeviceControl;  DriverObject->DriverUnload = MPU401Unload;    // Major hack to just get this damn thing working:    Status = InitDevice(RegistryPath, DriverObject);    // ????//    DPRINT("Enumerating devices at %wZ\n", RegistryPath);//    Status = EnumDeviceKeys(RegistryPath, PARMS_SUBKEY, InitDevice, (PVOID)&DeviceObject); // &Instance;    // check error  /* set up device extension *///  DeviceExtension = DeviceObject->DeviceExtension;//  DeviceExtension->BeepOn = FALSE;  return(STATUS_SUCCESS);}/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -