[ros-diffs] [silverblade] 27485: Renamed legacy mpu401 driver to mpu401_nt4 and disabled the building of all drivers in this directory (all are incomplete, none of them work and are superceded by the Kernel Streaming alternatives.) Leaving drivers in source tree for reference at present but they can eventually be removed.

silverblade at svn.reactos.org silverblade at svn.reactos.org
Sun Jul 8 18:07:02 CEST 2007


Author: silverblade
Date: Sun Jul  8 20:07:01 2007
New Revision: 27485

URL: http://svn.reactos.org/svn/reactos?rev=27485&view=rev
Log:
Renamed legacy mpu401 driver to mpu401_nt4 and disabled the building of 
all drivers in this directory (all are incomplete, none of them work and 
are superceded by the Kernel Streaming alternatives.) Leaving drivers in 
source tree for reference at present but they can eventually be removed.


Added:
    trunk/reactos/drivers/multimedia/audio/mpu401_nt4/
    trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.c
    trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.h
    trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.rbuild
    trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.rc
    trunk/reactos/drivers/multimedia/audio/mpu401_nt4/portio.c
    trunk/reactos/drivers/multimedia/audio/mpu401_nt4/readme.txt
    trunk/reactos/drivers/multimedia/audio/mpu401_nt4/sbdebug.h
    trunk/reactos/drivers/multimedia/audio/mpu401_nt4/settings.c
    trunk/reactos/drivers/multimedia/audio/mpu401_nt4/test.c
Removed:
    trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.c
    trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.h
    trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.rbuild
    trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.rc
    trunk/reactos/drivers/multimedia/audio/mpu401/portio.c
    trunk/reactos/drivers/multimedia/audio/mpu401/readme.txt
    trunk/reactos/drivers/multimedia/audio/mpu401/sbdebug.h
    trunk/reactos/drivers/multimedia/audio/mpu401/settings.c
    trunk/reactos/drivers/multimedia/audio/mpu401/test.c
Modified:
    trunk/reactos/drivers/multimedia/audio/directory.rbuild

Modified: trunk/reactos/drivers/multimedia/audio/directory.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/directory.rbuild?rev=27485&r1=27484&r2=27485&view=diff
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/directory.rbuild (original)
+++ trunk/reactos/drivers/multimedia/audio/directory.rbuild Sun Jul  8 20:07:01 2007
@@ -1,5 +1,9 @@
-<directory name="mpu401">
-	<xi:include href="mpu401/mpu401.rbuild" />
+<!--
+<directory name="mpu401_nt4">
+	<xi:include href="mpu401_nt4/mpu401.rbuild" />
+</directory>
+<directory name="sb16_nt4">
+	<xi:include href="sb16_nt4/sb16_nt4.rbuild" />
 </directory>
 <directory name="sndblst">
 	<xi:include href="sndblst/sndblst.rbuild" />
@@ -7,3 +11,4 @@
 <directory name="sound">
 	<xi:include href="sound/sound.rbuild" />
 </directory>
+-->

Removed: trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.c?rev=27484&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.c (original)
+++ trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.c (removed)
@@ -1,408 +1,0 @@
-/*
- *
- * 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 STDCALL
-MPU401Create(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 STDCALL
-MPU401Close(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 STDCALL
-MPU401Cleanup(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 STDCALL
-MPU401DeviceControl(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 STDCALL
-MPU401Unload(PDRIVER_OBJECT DriverObject)
-{
-  DPRINT("MPU401Unload() called!\n");
-}
-
-
-NTSTATUS STDCALL
-DriverEntry(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 */

Removed: trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.h?rev=27484&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.h (original)
+++ trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.h (removed)
@@ -1,155 +1,0 @@
-/*
- *
- * COPYRIGHT:            See COPYING in the top level directory
- * PROJECT:              ReactOS kernel
- * FILE:                 services/dd/mpu401/mpu401.h
- * PURPOSE:              MPU-401 MIDI device driver header
- * PROGRAMMER:           Andrew Greenwood
- * UPDATE HISTORY:
- *                       Sept 26, 2003: Created
- */
-
-#ifndef __INCLUDES_MPU401_H__
-#define __INCLUDES_MPU401_H__
-
-//#include <mmsystem.h>
-//#include <mmddk.h>
-//#include <winioctl.h>
-#include "../../../dll/win32/mmdrv/mmdef.h"
-
-#define DEFAULT_PORT    0x330
-#define DEFAULT_IRQ     9
-
-#define DEVICE_SUBKEY   L"Devices"
-#define PARMS_SUBKEY    L"Parameters"
-
-#define REGISTRY_PORT   L"Port"
-
-// At the moment, we just support a single device with fixed parameters:
-#define MPU401_PORT     DEFAULT_PORT
-#define MPU401_IRQ      DEFAULT_IRQ
-
-#define MPU401_TIMEOUT  10000
-
-/* OBSOLETE - see mmdef.h instead:
-#define IOCTL_SOUND_BASE FILE_DEVICE_SOUND
-// wave base 0
-#define IOCTL_MIDI_BASE  0x0080
-
-#define IOCTL_MIDI_GET_CAPABILITIES CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS)
-#define IOCTL_MIDI_SET_STATE CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0002, METHOD_BUFFERED, FILE_WRITE_ACCESS)
-#define IOCTL_MIDI_GET_STATE CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0003, METHOD_BUFFERED, FILE_WRITE_ACCESS)
-#define IOCTL_MIDI_SET_VOLUME CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0004, METHOD_BUFFERED, FILE_READ_ACCESS)
-#define IOCTL_MIDI_GET_VOLUME CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0005, METHOD_BUFFERED, FILE_READ_ACCESS)
-#define IOCTL_MIDI_PLAY CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0006, METHOD_BUFFERED, FILE_WRITE_ACCESS)
-#define IOCTL_MIDI_RECORD CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0007, METHOD_BUFFERED, FILE_WRITE_ACCESS)
-#define IOCTL_MIDI_CACHE_PATCHES CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0008, METHOD_BUFFERED, FILE_WRITE_ACCESS)
-#define IOCTL_MIDI_CACHE_DRUM_PATCHES CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0009, METHOD_BUFFERED, FILE_WRITE_ACCESS)
-*/
-
-// The MPU-401 has 2 ports, usually 0x330 and 0x331, which are known as
-// "data" and "status/command", respectively. These macros deal with
-// reading from and writing to these ports:
-
-#define MPU401_WRITE_DATA(bp, x)    WRITE_PORT_UCHAR((PUCHAR) bp, x)
-#define MPU401_READ_DATA(bp)        READ_PORT_UCHAR((PUCHAR) bp)
-#define MPU401_WRITE_COMMAND(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+1, x)
-#define MPU401_READ_STATUS(bp)      READ_PORT_UCHAR((PUCHAR) bp+1)
-
-
-// Flow control
-
-#define MPU401_READY_TO_SEND(bp) \
-    MPU401_READ_STATUS(bp) & 0x80
-
-#define MPU401_READY_TO_RECEIVE(bp) \
-    MPU401_READ_STATUS(bp) & 0x40
-
-
-#define MPU401_WRITE_BYTE(bp, x) \
-    if (WaitToSend(bp)) MPU401_WRITE_DATA(bp, x)
-
-#define MPU401_WRITE_MESSAGE(bp, status, da, db) \
-    MPU401_WRITE(bp, status); \
-    MPU401_WRITE(bp, da); \
-    MPU401_WRITE(bp, db)
-
-//#define MPU401_READ(bp)
-//    if (WaitToRead(bp)) ... ???
-
-/*
-    DEVICE_EXTENSION contains the settings for each individual device
-*/
-
-typedef struct _DEVICE_EXTENSION
-{
-    PUNICODE_STRING RegistryPath;
-    PDRIVER_OBJECT DriverObject;
-    ULONG Port;
-    ULONG IRQ;
-//  KDPC Dpc;
-//  KTIMER Timer;
-//  KEVENT Event;
-//  BOOLEAN BeepOn;
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
-
-/*
-    DEVICE_INSTANCE contains ???
-*/
-
-typedef struct _DEVICE_INSTANCE
-{
-    // pPrevGDI
-    PDRIVER_OBJECT DriverObject;
-} DEVICE_INSTANCE, *PDEVICE_INSTANCE;
-
-/*
-    CONFIG contains device parameters (port/IRQ)
-    THIS STRUCTURE IS REDUNDANT
-*/
-
-//typedef struct _CONFIG
-//{
-//    ULONG Port;
-//    ULONG IRQ;
-//} CONFIG, *PCONFIG;
-
-/*
-    Some callback typedefs
-*/
-
-typedef NTSTATUS REGISTRY_CALLBACK_ROUTINE(PWSTR RegistryPath, PVOID Context);
-typedef REGISTRY_CALLBACK_ROUTINE *PREGISTRY_CALLBACK_ROUTINE;
-
-
-/*
-    Prototypes for functions in portio.c :
-*/
-
-BOOLEAN WaitToSend(ULONG BasePort);
-BOOLEAN WaitToReceive(ULONG BasePort);
-BOOLEAN InitUARTMode(ULONG BasePort);
-
-/*
-    Prototypes for functions in settings.c :
-*/
-
-NTSTATUS STDCALL EnumDeviceKeys(
-    IN PUNICODE_STRING RegistryPath,
-    IN PWSTR SubKey,
-    IN PREGISTRY_CALLBACK_ROUTINE Callback,
-    IN PVOID Context);
-
-NTSTATUS STDCALL LoadSettings(
-    IN  PWSTR ValueName,
-    IN  ULONG ValueType,
-    IN  PVOID ValueData,
-    IN  ULONG ValueLength,
-    IN  PVOID Context,
-    IN  PVOID EntryContext);
-
-NTSTATUS STDCALL
-DriverEntry(PDRIVER_OBJECT DriverObject,
-	    PUNICODE_STRING RegistryPath);
-
-#endif

Removed: trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.rbuild?rev=27484&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.rbuild (original)
+++ trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.rbuild (removed)
@@ -1,10 +1,0 @@
-<module name="mpu401" type="kernelmodedriver">
-	<include base="mpu401">.</include>
-        <define name="__USE_W32API" />
-	<library>ntoskrnl</library>
-	<library>hal</library>
-	<file>mpu401.c</file>
-	<file>portio.c</file>
-	<file>settings.c</file>
-	<file>mpu401.rc</file>
-</module>

Removed: trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.rc
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.rc?rev=27484&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.rc (original)
+++ trunk/reactos/drivers/multimedia/audio/mpu401/mpu401.rc (removed)
@@ -1,7 +1,0 @@
-/* $Id$ */
-
-#define REACTOS_VERSION_DLL
-#define REACTOS_STR_FILE_DESCRIPTION	"MPU-401 MIDI Driver\0"
-#define REACTOS_STR_INTERNAL_NAME	"mpu401\0"
-#define REACTOS_STR_ORIGINAL_FILENAME	"mpu401.sys\0"
-#include <reactos/version.rc>

Removed: trunk/reactos/drivers/multimedia/audio/mpu401/portio.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401/portio.c?rev=27484&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401/portio.c (original)
+++ trunk/reactos/drivers/multimedia/audio/mpu401/portio.c (removed)
@@ -1,96 +1,0 @@
-/*
- *
- * COPYRIGHT:            See COPYING in the top level directory
- * PROJECT:              ReactOS kernel
- * FILE:                 services/dd/mpu401/portio.c (see also mpu401.h)
- * PURPOSE:              MPU-401 MIDI port I/O helper
- * PROGRAMMER:           Andrew Greenwood
- * UPDATE HISTORY:
- *                       Sept 26, 2003: Created
- */
-
-#include <ntddk.h>
-#include "mpu401.h"
-
-
-BOOLEAN WaitToSend(ULONG BasePort)
-{
-    int TimeOut;
-
-    DbgPrint("WaitToSend ");
-
-    // Check if it's OK to send
-    for (TimeOut = MPU401_TIMEOUT;
-         ! MPU401_READY_TO_SEND(BasePort) && TimeOut > 0;
-         TimeOut --);
-
-    // If a time-out occurs, we report failure
-    if (! TimeOut)
-    {
-        DbgPrint("FAILED\n");
-        return FALSE;
-    }
-
-    DbgPrint("SUCCEEDED\n");
-
-    return TRUE;
-}
-
-
-BOOLEAN WaitToReceive(ULONG BasePort)
-{
-    int TimeOut;
-
-    DbgPrint("WaitToSend ");
-
-    // Check if it's OK to receive
-    for (TimeOut = MPU401_TIMEOUT;
-         ! MPU401_READY_TO_RECEIVE(BasePort) && TimeOut > 0;
-         TimeOut --);
-
-    // If a time-out occurs, we report failure
-    if (! TimeOut)
-    {
-        DbgPrint("FAILED\n");
-        return FALSE;
-    }
-
-    DbgPrint("SUCCEEDED\n");
-
-    return TRUE;
-}
-
-
-BOOLEAN InitUARTMode(ULONG BasePort)
-{
-    ULONG TimeOut;
-    UCHAR Status = 0;
-
-    DbgPrint("InitUARTMode() called\n");
-
-    // Check if it's OK to send
-    if (! WaitToSend(BasePort))
-        return FALSE;
-
-    DbgPrint("Resetting MPU401\n");
-
-    // Send an MPU reset:
-    MPU401_WRITE_COMMAND(BasePort, 0xff);
-
-    // Check if it's OK to receive (some cards will ignore the above reset
-    // command and so will not issue an ACK, so time out is NOT an error)
-    DbgPrint("Waiting for an ACK\n");
-    if (WaitToReceive(BasePort))
-    {
-        // Check to make sure the reset was acknowledged:
-        for (TimeOut = MPU401_TIMEOUT;
-             (Status = (MPU401_READ_DATA(BasePort) & 0xfe) && TimeOut > 0);
-             TimeOut --);
-    }
-
-    DbgPrint("Entering UART mode\n");
-    // Now we kick the MPU401 into UART ("dumb") mode
-    MPU401_WRITE_COMMAND(BasePort, 0x3f);
-
-    return TRUE;
-}

Removed: trunk/reactos/drivers/multimedia/audio/mpu401/readme.txt
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401/readme.txt?rev=27484&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401/readme.txt (original)
+++ trunk/reactos/drivers/multimedia/audio/mpu401/readme.txt (removed)
@@ -1,28 +1,0 @@
-----------------------------------
-REACTOS MPU-401 MIDI DEVICE DRIVER
-by Andrew Greenwood
-----------------------------------
-
-This driver initializes the MPU-401 MIDI/joystick port found on
-most sound cards, and allows the sending of simple messages.
-
-It's far from complete, and at present will only support 1 device.
-
-In Bochs, the MIDI output will be played using whatever device is
-set up in Windows as your MIDI output.
-
-For real hardware, the output will be played to whatever device is
-attached to your MIDI/joystick port, or, in some cases, the wave-table
-or other synth on-board your card (note: this is NOT an FM synth
-driver!)
-
-
-Thanks to Vizzini and all the other great ReactOS developers for
-helping me code this driver and also for giving me encouragement.
-
-I'd also like to thank Jeff Glatt, whose MIDI and MPU-401
-documentation has been a valuable resource to me over the past few
-years, and who provided me with almost all of my knowledge of MIDI
-and MPU-401. His site is at: www.borg.com/~jglatt/
-
-- Andrew "Silver Blade" Greenwood

Removed: trunk/reactos/drivers/multimedia/audio/mpu401/sbdebug.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401/sbdebug.h?rev=27484&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401/sbdebug.h (original)
+++ trunk/reactos/drivers/multimedia/audio/mpu401/sbdebug.h (removed)
@@ -1,24 +1,0 @@
-#ifndef NDEBUG
-#define TEST_STATUS(s) \
-        if (! NT_SUCCESS(s)) \
-        { \
-            if (s == STATUS_NO_MORE_ENTRIES) \
-                DPRINT("NTSTATUS == NO MORE ENTRIES\n") \
-            else if (s == STATUS_BUFFER_OVERFLOW) \
-                DPRINT("NTSTATUS == BUFFER OVERFLOW\n") \
-            else if (s == STATUS_BUFFER_TOO_SMALL) \
-                DPRINT("NTSTATUS == BUFFER TOO SMALL\n") \
-            else if (s == STATUS_INVALID_PARAMETER) \
-                DPRINT("NTSTATUS == INVALID PARAMETER\n") \
-            else if (s == STATUS_OBJECT_NAME_NOT_FOUND) \
-                DPRINT("NTSTATUS == OBJECT NAME NOT FOUND\n") \
-            else if (s == STATUS_INVALID_HANDLE) \
-                DPRINT("NTATATUS == INVALID_HANDLE\n") \
-            else if (s == STATUS_ACCESS_DENIED) \
-                DPRINT("NTSTATUS == ACCESS_DENIED\n") \
-            else \
-                DPRINT("NTSTATUS == FAILURE (?)\n"); \
-        }
-#else
-#define TEST_STATUS(s)
-#endif

Removed: trunk/reactos/drivers/multimedia/audio/mpu401/settings.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401/settings.c?rev=27484&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401/settings.c (original)
+++ trunk/reactos/drivers/multimedia/audio/mpu401/settings.c (removed)
@@ -1,307 +1,0 @@
-/*
- *
- * COPYRIGHT:            See COPYING in the top level directory
- * PROJECT:              ReactOS kernel
- * FILE:                 services/dd/mpu401/settings.c
- * PURPOSE:              MPU-401 MIDI device driver setting management
- * PROGRAMMER:           Andrew Greenwood
- * UPDATE HISTORY:
- *                       Sept 27, 2003: Created
- */
-
-#include <ntddk.h>
-
-#include "mpu401.h"
-
-#define NDEBUG
-#include <debug.h>
-#include "sbdebug.h"  // our own debug helper
-
-#if 0
-static NTSTATUS
-OpenDevicesKey(
-    IN PWSTR RegistryPath,
-    OUT PHANDLE Key)
-/*
-    Description:
-        Create a volatile key under this driver's Services node to contain
-        the device name list.
-
-    Parameters:
-        RegistryPath    The location of the registry entry
-        Key             The key in the registry
-
-    Return Value:
-        NT status STATUS_SUCCESS if successful (duh...)
-*/
-{
-    NTSTATUS s;
-    HANDLE hKey;
-    OBJECT_ATTRIBUTES oa;
-    UNICODE_STRING uStr;
-
-    // Attempt to open the key
-
-    RtlInitUnicodeString(&uStr, RegistryPath);
-
-    InitializeObjectAttributes(&oa, &uStr, OBJ_CASE_INSENSITIVE, NULL,
-                                (PSECURITY_DESCRIPTOR)NULL);
-
-    s = ZwOpenKey(&hKey, KEY_CREATE_SUB_KEY, &oa);
-
-    if (! NT_SUCCESS(s))
-        return s;   // Problem
-
-
-    // Now create sub key
-
-    RtlInitUnicodeString(&uStr, (PWSTR) DEVICE_SUBKEY);
-
-    InitializeObjectAttributes(&oa, &uStr, OBJ_CASE_INSENSITIVE, hKey,
-                                (PSECURITY_DESCRIPTOR)NULL);
-
-    s = ZwCreateKey(Key, KEY_ALL_ACCESS, &oa, 0, NULL, REG_OPTION_VOLATILE,
-                    NULL);
-
-    ZwClose(hKey);
-
-    return s;
-}
-#endif
-
-
-NTSTATUS STDCALL EnumDeviceKeys(
-    IN PUNICODE_STRING RegistryPath,
-    IN PWSTR SubKey,
-    IN PREGISTRY_CALLBACK_ROUTINE Callback,
-    IN PVOID Context)
-/*
-    Description:
-        Enumerate the device subkeys in the driver's registry entry, and
-        call the specified callback routine for each device.
-
-    Parameters:
-        RegistryPath    The location of the registry entry
-        Subkey          The device's subkey
-        Callback        A routine called for each device
-        Context         ???
-
-    Return Value:
-        NT status STATUS_SUCCESS if successful
-*/
-{
-    NTSTATUS s;
-    OBJECT_ATTRIBUTES oa;
-    HANDLE hKey, hSubKey;
-    UNICODE_STRING SubkeyName;
-    ULONG i;
-
-    // Attempt to open the key
-
-    InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE,
-                                NULL, (PSECURITY_DESCRIPTOR)NULL);
-
-    s = ZwOpenKey(&hKey, KEY_READ, &oa);
-
-        TEST_STATUS(s); // debugging
-
-    if (! NT_SUCCESS(s))
-        return s;   // Problem
-
-    RtlInitUnicodeString(&SubkeyName, SubKey);
-
-    DPRINT("Subkey: %wZ\n", &SubkeyName);
-
-    InitializeObjectAttributes(&oa, &SubkeyName, OBJ_CASE_INSENSITIVE,
-                                hKey, (PSECURITY_DESCRIPTOR)NULL);
-
-    s = ZwOpenKey(&hSubKey, KEY_ENUMERATE_SUB_KEYS, &oa);
-
-    ZwClose(hKey);
-
-        TEST_STATUS(s); // debugging
-
-    if (! NT_SUCCESS(s))
-        return s;
-
-
-    // And now, the enumeration
-
-    for (i = 0;; i ++)
-    {
-        KEY_BASIC_INFORMATION Info;
-        PKEY_BASIC_INFORMATION pInfo;
-        ULONG ResultLength = 0;
-        ULONG Size = 0;
-        PWSTR Pos;
-        PWSTR Name;
-
-        // Find the length of the subkey data
-
-//        Info.NameLength = 0;    // TEMPORARY!
-
-        s = ZwEnumerateKey(hSubKey, i, KeyBasicInformation, &Info,
-                            sizeof(Info), &ResultLength);
-
-        if (s == STATUS_NO_MORE_ENTRIES)
-            break;
-
-        DPRINT("Found an entry, allocating memory...\n");
-
-//        Size = Info.NameLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
-        Size = ResultLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
-
-        DPRINT("Size is %d\n", Size);
-
-        pInfo = (PKEY_BASIC_INFORMATION) ExAllocatePool(PagedPool, Size);
-
-        if (pInfo == NULL)
-        {
-            DPRINT("INSUFFICIENT RESOURCES!\n");
-            s = STATUS_INSUFFICIENT_RESOURCES;
-            break;
-        }
-
-        DPRINT("Re-enumerating...\n");
-
-        s = ZwEnumerateKey(hSubKey, i, KeyBasicInformation, pInfo, Size,
-                            &ResultLength);
-
-//        TEST_STATUS(s); // debugging
-
-        if (! NT_SUCCESS(s))
-        {
-            ExFreePool((PVOID) pInfo);
-            s = STATUS_INTERNAL_ERROR;
-            break;
-        }
-
-        DPRINT("Allocating memory for name...\n");
-
-        Name = ExAllocatePool(PagedPool,
-                          RegistryPath->Length + sizeof(WCHAR) +
-                          SubkeyName.Length + sizeof(WCHAR) +
-                          pInfo->NameLength + sizeof(UNICODE_NULL));
-
-        if (Name == NULL)
-        {
-            DPRINT("INSUFFICIENT RESOURCES!");
-            ExFreePool((PVOID) pInfo);
-            return STATUS_INSUFFICIENT_RESOURCES;
-        }
-
-        // Copy the key name
-        RtlCopyMemory((PVOID)Name, (PVOID)RegistryPath->Buffer, RegistryPath->Length);
-        Pos = Name + (RegistryPath->Length / sizeof(WCHAR));
-        Pos[0] = '\\';
-        Pos++;
-
-        // Copy the parameters sub key name
-        RtlCopyMemory((PVOID)Pos, (PVOID)SubKey, SubkeyName.Length);    //SubkeyName?
-        Pos += SubkeyName.Length / sizeof(WCHAR);
-        Pos[0] = '\\';
-        Pos ++;
-
-        // Copy the device sub key name
-        RtlCopyMemory((PVOID)Pos, (PVOID)pInfo->Name, pInfo->NameLength);
-        Pos += pInfo->NameLength / sizeof(WCHAR);
-        Pos[0] = UNICODE_NULL;
-
-        ExFreePool((PVOID)pInfo);
-
-        DPRINT("Calling callback...\n");
-
-        s = (*Callback)(Name, Context);
-
-        if (! NT_SUCCESS(s))
-        {   DPRINT("Callback FAILED\n");
-            break;}
-    }
-
-    ZwClose(hSubKey);
-
-    DPRINT("%d device registry keys found\n", i);
-
-    if ((i == 0) && (s == STATUS_NO_MORE_ENTRIES))
-        return STATUS_DEVICE_CONFIGURATION_ERROR;
-
-    return s == STATUS_NO_MORE_ENTRIES ? STATUS_SUCCESS : s;
-}
-
-
-
-NTSTATUS STDCALL LoadSettings(
-    IN  PWSTR ValueName,
-    IN  ULONG ValueType,
-    IN  PVOID ValueData,
-    IN  ULONG ValueLength,
-    IN  PVOID Context,
-    IN  PVOID EntryContext)
-/*
-    Description:
-        Read the settings for a particular device
-
-    Parameters:
-        ValueName       The value to read from the registry
-        ValueType       ?
-        ValueData       ?
-        ValueLength     ?
-        Context         The configuration structure to write to
-        EntryContext    ?
-
-    Return Value:
-        NT status STATUS_SUCCESS if successful
-*/
-{
-    PDEVICE_EXTENSION DeviceInfo = Context;
-
-    if (ValueType == REG_DWORD)
-    {
-        if (! _wcsicmp(ValueName, REGISTRY_PORT))
-        {
-            DeviceInfo->Port = *(PULONG) ValueData;
-            DPRINT("Registry port = 0x%x\n", DeviceInfo->Port);
-        }
-
-        // More to come... (config.c)
-    }
-
-    else
-    {
-        // ?
-    }
-
-    return STATUS_SUCCESS;
-}
-
-
-#if 0
-static NTSTATUS SaveSettings(
-    IN  PWSTR RegistryPath,
-    IN  ULONG Port,
-    IN  ULONG IRQ,
-    IN  ULONG DMA)
-/*
-    Description:
-        Saves the settings for a particular device
-
-    Parameters:
-        RegistryPath    Where to save the settings to
-        Port            The device's port number
-        IRQ             The device's interrupt number
-        DMA             The device's DMA channel
-
-    Return Value:
-        NT status STATUS_SUCCESS if successful
-*/
-{
-//    NTSTATUS s;
-
-    DPRINT("SaveSettings() unimplemented\n");
-
-//    UNIMPLEMENTED;
-
-    return STATUS_SUCCESS;
-}
-#endif
-

Removed: trunk/reactos/drivers/multimedia/audio/mpu401/test.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401/test.c?rev=27484&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401/test.c (original)
+++ trunk/reactos/drivers/multimedia/audio/mpu401/test.c (removed)
@@ -1,70 +1,0 @@
-#include <stdio.h>
-#include <windows.h>
-#include <ntddk.h>
-#include "mpu401.h"
-
-int main()
-{
-//    NTSTATUS s;
-//    PHANDLE Handle;
-//    PIO_STATUS_BLOCK Status;
-    DWORD BytesReturned;
-    BYTE Test[3]; // Will store MIDI data
-    BYTE Notes[] = {50, 52, 54, 55, 57, 59, 61};
-    HANDLE Device;
-    UINT Note;
-    UINT Junk;
-
-    printf("Test program for MPU401 driver\n");
-
-    Device = CreateFile("\\\\.\\MPU401_Out_0", GENERIC_READ | GENERIC_WRITE,
-                        FILE_SHARE_READ | FILE_SHARE_WRITE,
-                        NULL,
-                        OPEN_EXISTING,
-                        FILE_FLAG_NO_BUFFERING,
-                        NULL);
-
-    if (Device == INVALID_HANDLE_VALUE)
-    {
-        printf("Device is busy or could not be found.\n");
-        return -1;
-    }
-
-    printf("Device is open, let's play some music...\n");
-
-        Test[0] = 0x90;
-        Test[2] = 0x7f;
-
-    for (Note = 0; Note < sizeof(Notes); Note ++)
-    {
-        Test[1] = Notes[Note];
-
-    DeviceIoControl(
-        Device,
-        IOCTL_MIDI_PLAY,
-        &Test,
-        sizeof(Test),
-        NULL,
-        0,
-        &BytesReturned,
-        NULL
-        );
-
-        for (Junk = 0; Junk < 100000; Junk ++);   // Pause
-    }
-
-
-/*    s = IoCreateFile(Handle, GENERIC_READ | GENERIC_WRITE,
-                     OBJ_KERNEL_HANDLE,
-                     Status,
-                     0,
-                     FILE_SHARE_READ | FILE_SHARE_WRITE,
-                     FILE_OPEN,
-                     FILE_NON_DIRECTORY_FILE,
-                     NULL,
-                     0,
-                     CreateFileTypeNone,
-                     NULL,
-                     0);
-*/
-}

Added: trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.c?rev=27485&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.c (added)
+++ trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.c Sun Jul  8 20:07:01 2007
@@ -1,0 +1,408 @@
+/*
+ *
+ * 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 STDCALL
+MPU401Create(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 STDCALL
+MPU401Close(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 STDCALL
+MPU401Cleanup(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 STDCALL
+MPU401DeviceControl(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 STDCALL
+MPU401Unload(PDRIVER_OBJECT DriverObject)
+{
+  DPRINT("MPU401Unload() called!\n");
+}
+
+
+NTSTATUS STDCALL
+DriverEntry(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 */

Added: trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.h?rev=27485&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.h (added)
+++ trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.h Sun Jul  8 20:07:01 2007
@@ -1,0 +1,155 @@
+/*
+ *
+ * COPYRIGHT:            See COPYING in the top level directory
+ * PROJECT:              ReactOS kernel
+ * FILE:                 services/dd/mpu401/mpu401.h
+ * PURPOSE:              MPU-401 MIDI device driver header
+ * PROGRAMMER:           Andrew Greenwood
+ * UPDATE HISTORY:
+ *                       Sept 26, 2003: Created
+ */
+
+#ifndef __INCLUDES_MPU401_H__
+#define __INCLUDES_MPU401_H__
+
+//#include <mmsystem.h>
+//#include <mmddk.h>
+//#include <winioctl.h>
+#include "../../../dll/win32/mmdrv/mmdef.h"
+
+#define DEFAULT_PORT    0x330
+#define DEFAULT_IRQ     9
+
+#define DEVICE_SUBKEY   L"Devices"
+#define PARMS_SUBKEY    L"Parameters"
+
+#define REGISTRY_PORT   L"Port"
+
+// At the moment, we just support a single device with fixed parameters:
+#define MPU401_PORT     DEFAULT_PORT
+#define MPU401_IRQ      DEFAULT_IRQ
+
+#define MPU401_TIMEOUT  10000
+
+/* OBSOLETE - see mmdef.h instead:
+#define IOCTL_SOUND_BASE FILE_DEVICE_SOUND
+// wave base 0
+#define IOCTL_MIDI_BASE  0x0080
+
+#define IOCTL_MIDI_GET_CAPABILITIES CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS)
+#define IOCTL_MIDI_SET_STATE CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0002, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define IOCTL_MIDI_GET_STATE CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0003, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define IOCTL_MIDI_SET_VOLUME CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0004, METHOD_BUFFERED, FILE_READ_ACCESS)
+#define IOCTL_MIDI_GET_VOLUME CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0005, METHOD_BUFFERED, FILE_READ_ACCESS)
+#define IOCTL_MIDI_PLAY CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0006, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define IOCTL_MIDI_RECORD CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0007, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define IOCTL_MIDI_CACHE_PATCHES CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0008, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define IOCTL_MIDI_CACHE_DRUM_PATCHES CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0009, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+*/
+
+// The MPU-401 has 2 ports, usually 0x330 and 0x331, which are known as
+// "data" and "status/command", respectively. These macros deal with
+// reading from and writing to these ports:
+
+#define MPU401_WRITE_DATA(bp, x)    WRITE_PORT_UCHAR((PUCHAR) bp, x)
+#define MPU401_READ_DATA(bp)        READ_PORT_UCHAR((PUCHAR) bp)
+#define MPU401_WRITE_COMMAND(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+1, x)
+#define MPU401_READ_STATUS(bp)      READ_PORT_UCHAR((PUCHAR) bp+1)
+
+
+// Flow control
+
+#define MPU401_READY_TO_SEND(bp) \
+    MPU401_READ_STATUS(bp) & 0x80
+
+#define MPU401_READY_TO_RECEIVE(bp) \
+    MPU401_READ_STATUS(bp) & 0x40
+
+
+#define MPU401_WRITE_BYTE(bp, x) \
+    if (WaitToSend(bp)) MPU401_WRITE_DATA(bp, x)
+
+#define MPU401_WRITE_MESSAGE(bp, status, da, db) \
+    MPU401_WRITE(bp, status); \
+    MPU401_WRITE(bp, da); \
+    MPU401_WRITE(bp, db)
+
+//#define MPU401_READ(bp)
+//    if (WaitToRead(bp)) ... ???
+
+/*
+    DEVICE_EXTENSION contains the settings for each individual device
+*/
+
+typedef struct _DEVICE_EXTENSION
+{
+    PUNICODE_STRING RegistryPath;
+    PDRIVER_OBJECT DriverObject;
+    ULONG Port;
+    ULONG IRQ;
+//  KDPC Dpc;
+//  KTIMER Timer;
+//  KEVENT Event;
+//  BOOLEAN BeepOn;
+} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
+
+/*
+    DEVICE_INSTANCE contains ???
+*/
+
+typedef struct _DEVICE_INSTANCE
+{
+    // pPrevGDI
+    PDRIVER_OBJECT DriverObject;
+} DEVICE_INSTANCE, *PDEVICE_INSTANCE;
+
+/*
+    CONFIG contains device parameters (port/IRQ)
+    THIS STRUCTURE IS REDUNDANT
+*/
+
+//typedef struct _CONFIG
+//{
+//    ULONG Port;
+//    ULONG IRQ;
+//} CONFIG, *PCONFIG;
+
+/*
+    Some callback typedefs
+*/
+
+typedef NTSTATUS REGISTRY_CALLBACK_ROUTINE(PWSTR RegistryPath, PVOID Context);
+typedef REGISTRY_CALLBACK_ROUTINE *PREGISTRY_CALLBACK_ROUTINE;
+
+
+/*
+    Prototypes for functions in portio.c :
+*/
+
+BOOLEAN WaitToSend(ULONG BasePort);
+BOOLEAN WaitToReceive(ULONG BasePort);
+BOOLEAN InitUARTMode(ULONG BasePort);
+
+/*
+    Prototypes for functions in settings.c :
+*/
+
+NTSTATUS STDCALL EnumDeviceKeys(
+    IN PUNICODE_STRING RegistryPath,
+    IN PWSTR SubKey,
+    IN PREGISTRY_CALLBACK_ROUTINE Callback,
+    IN PVOID Context);
+
+NTSTATUS STDCALL LoadSettings(
+    IN  PWSTR ValueName,
+    IN  ULONG ValueType,
+    IN  PVOID ValueData,
+    IN  ULONG ValueLength,
+    IN  PVOID Context,
+    IN  PVOID EntryContext);
+
+NTSTATUS STDCALL
+DriverEntry(PDRIVER_OBJECT DriverObject,
+	    PUNICODE_STRING RegistryPath);
+
+#endif

Added: trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.rbuild?rev=27485&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.rbuild (added)
+++ trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.rbuild Sun Jul  8 20:07:01 2007
@@ -1,0 +1,15 @@
+<!--
+	Conflicts with Kernel Streaming MPU401 driver.
+	Here for reference only.
+-->
+
+<module name="mpu401" type="kernelmodedriver">
+	<include base="mpu401_nt4">.</include>
+        <define name="__USE_W32API" />
+	<library>ntoskrnl</library>
+	<library>hal</library>
+	<file>mpu401.c</file>
+	<file>portio.c</file>
+	<file>settings.c</file>
+	<file>mpu401.rc</file>
+</module>

Added: trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.rc
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.rc?rev=27485&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.rc (added)
+++ trunk/reactos/drivers/multimedia/audio/mpu401_nt4/mpu401.rc Sun Jul  8 20:07:01 2007
@@ -1,0 +1,7 @@
+/* $Id: mpu401.rc 21285 2006-03-10 23:22:58Z jimtabor $ */
+
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION	"MPU-401 MIDI Driver\0"
+#define REACTOS_STR_INTERNAL_NAME	"mpu401\0"
+#define REACTOS_STR_ORIGINAL_FILENAME	"mpu401.sys\0"
+#include <reactos/version.rc>

Added: trunk/reactos/drivers/multimedia/audio/mpu401_nt4/portio.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401_nt4/portio.c?rev=27485&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401_nt4/portio.c (added)
+++ trunk/reactos/drivers/multimedia/audio/mpu401_nt4/portio.c Sun Jul  8 20:07:01 2007
@@ -1,0 +1,96 @@
+/*
+ *
+ * COPYRIGHT:            See COPYING in the top level directory
+ * PROJECT:              ReactOS kernel
+ * FILE:                 services/dd/mpu401/portio.c (see also mpu401.h)
+ * PURPOSE:              MPU-401 MIDI port I/O helper
+ * PROGRAMMER:           Andrew Greenwood
+ * UPDATE HISTORY:
+ *                       Sept 26, 2003: Created
+ */
+
+#include <ntddk.h>
+#include "mpu401.h"
+
+
+BOOLEAN WaitToSend(ULONG BasePort)
+{
+    int TimeOut;
+
+    DbgPrint("WaitToSend ");
+
+    // Check if it's OK to send
+    for (TimeOut = MPU401_TIMEOUT;
+         ! MPU401_READY_TO_SEND(BasePort) && TimeOut > 0;
+         TimeOut --);
+
+    // If a time-out occurs, we report failure
+    if (! TimeOut)
+    {
+        DbgPrint("FAILED\n");
+        return FALSE;
+    }
+
+    DbgPrint("SUCCEEDED\n");
+
+    return TRUE;
+}
+
+
+BOOLEAN WaitToReceive(ULONG BasePort)
+{
+    int TimeOut;
+
+    DbgPrint("WaitToSend ");
+
+    // Check if it's OK to receive
+    for (TimeOut = MPU401_TIMEOUT;
+         ! MPU401_READY_TO_RECEIVE(BasePort) && TimeOut > 0;
+         TimeOut --);
+
+    // If a time-out occurs, we report failure
+    if (! TimeOut)
+    {
+        DbgPrint("FAILED\n");
+        return FALSE;
+    }
+
+    DbgPrint("SUCCEEDED\n");
+
+    return TRUE;
+}
+
+
+BOOLEAN InitUARTMode(ULONG BasePort)
+{
+    ULONG TimeOut;
+    UCHAR Status = 0;
+
+    DbgPrint("InitUARTMode() called\n");
+
+    // Check if it's OK to send
+    if (! WaitToSend(BasePort))
+        return FALSE;
+
+    DbgPrint("Resetting MPU401\n");
+
+    // Send an MPU reset:
+    MPU401_WRITE_COMMAND(BasePort, 0xff);
+
+    // Check if it's OK to receive (some cards will ignore the above reset
+    // command and so will not issue an ACK, so time out is NOT an error)
+    DbgPrint("Waiting for an ACK\n");
+    if (WaitToReceive(BasePort))
+    {
+        // Check to make sure the reset was acknowledged:
+        for (TimeOut = MPU401_TIMEOUT;
+             (Status = (MPU401_READ_DATA(BasePort) & 0xfe) && TimeOut > 0);
+             TimeOut --);
+    }
+
+    DbgPrint("Entering UART mode\n");
+    // Now we kick the MPU401 into UART ("dumb") mode
+    MPU401_WRITE_COMMAND(BasePort, 0x3f);
+
+    return TRUE;
+}

Added: trunk/reactos/drivers/multimedia/audio/mpu401_nt4/readme.txt
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401_nt4/readme.txt?rev=27485&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401_nt4/readme.txt (added)
+++ trunk/reactos/drivers/multimedia/audio/mpu401_nt4/readme.txt Sun Jul  8 20:07:01 2007
@@ -1,0 +1,28 @@
+----------------------------------
+REACTOS MPU-401 MIDI DEVICE DRIVER
+by Andrew Greenwood
+----------------------------------
+
+This driver initializes the MPU-401 MIDI/joystick port found on
+most sound cards, and allows the sending of simple messages.
+
+It's far from complete, and at present will only support 1 device.
+
+In Bochs, the MIDI output will be played using whatever device is
+set up in Windows as your MIDI output.
+
+For real hardware, the output will be played to whatever device is
+attached to your MIDI/joystick port, or, in some cases, the wave-table
+or other synth on-board your card (note: this is NOT an FM synth
+driver!)
+
+
+Thanks to Vizzini and all the other great ReactOS developers for
+helping me code this driver and also for giving me encouragement.
+
+I'd also like to thank Jeff Glatt, whose MIDI and MPU-401
+documentation has been a valuable resource to me over the past few
+years, and who provided me with almost all of my knowledge of MIDI
+and MPU-401. His site is at: www.borg.com/~jglatt/
+
+- Andrew "Silver Blade" Greenwood

Added: trunk/reactos/drivers/multimedia/audio/mpu401_nt4/sbdebug.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401_nt4/sbdebug.h?rev=27485&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401_nt4/sbdebug.h (added)
+++ trunk/reactos/drivers/multimedia/audio/mpu401_nt4/sbdebug.h Sun Jul  8 20:07:01 2007
@@ -1,0 +1,24 @@
+#ifndef NDEBUG
+#define TEST_STATUS(s) \
+        if (! NT_SUCCESS(s)) \
+        { \
+            if (s == STATUS_NO_MORE_ENTRIES) \
+                DPRINT("NTSTATUS == NO MORE ENTRIES\n") \
+            else if (s == STATUS_BUFFER_OVERFLOW) \
+                DPRINT("NTSTATUS == BUFFER OVERFLOW\n") \
+            else if (s == STATUS_BUFFER_TOO_SMALL) \
+                DPRINT("NTSTATUS == BUFFER TOO SMALL\n") \
+            else if (s == STATUS_INVALID_PARAMETER) \
+                DPRINT("NTSTATUS == INVALID PARAMETER\n") \
+            else if (s == STATUS_OBJECT_NAME_NOT_FOUND) \
+                DPRINT("NTSTATUS == OBJECT NAME NOT FOUND\n") \
+            else if (s == STATUS_INVALID_HANDLE) \
+                DPRINT("NTATATUS == INVALID_HANDLE\n") \
+            else if (s == STATUS_ACCESS_DENIED) \
+                DPRINT("NTSTATUS == ACCESS_DENIED\n") \
+            else \
+                DPRINT("NTSTATUS == FAILURE (?)\n"); \
+        }
+#else
+#define TEST_STATUS(s)
+#endif

Added: trunk/reactos/drivers/multimedia/audio/mpu401_nt4/settings.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401_nt4/settings.c?rev=27485&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401_nt4/settings.c (added)
+++ trunk/reactos/drivers/multimedia/audio/mpu401_nt4/settings.c Sun Jul  8 20:07:01 2007
@@ -1,0 +1,307 @@
+/*
+ *
+ * COPYRIGHT:            See COPYING in the top level directory
+ * PROJECT:              ReactOS kernel
+ * FILE:                 services/dd/mpu401/settings.c
+ * PURPOSE:              MPU-401 MIDI device driver setting management
+ * PROGRAMMER:           Andrew Greenwood
+ * UPDATE HISTORY:
+ *                       Sept 27, 2003: Created
+ */
+
+#include <ntddk.h>
+
+#include "mpu401.h"
+
+#define NDEBUG
+#include <debug.h>
+#include "sbdebug.h"  // our own debug helper
+
+#if 0
+static NTSTATUS
+OpenDevicesKey(
+    IN PWSTR RegistryPath,
+    OUT PHANDLE Key)
+/*
+    Description:
+        Create a volatile key under this driver's Services node to contain
+        the device name list.
+
+    Parameters:
+        RegistryPath    The location of the registry entry
+        Key             The key in the registry
+
+    Return Value:
+        NT status STATUS_SUCCESS if successful (duh...)
+*/
+{
+    NTSTATUS s;
+    HANDLE hKey;
+    OBJECT_ATTRIBUTES oa;
+    UNICODE_STRING uStr;
+
+    // Attempt to open the key
+
+    RtlInitUnicodeString(&uStr, RegistryPath);
+
+    InitializeObjectAttributes(&oa, &uStr, OBJ_CASE_INSENSITIVE, NULL,
+                                (PSECURITY_DESCRIPTOR)NULL);
+
+    s = ZwOpenKey(&hKey, KEY_CREATE_SUB_KEY, &oa);
+
+    if (! NT_SUCCESS(s))
+        return s;   // Problem
+
+
+    // Now create sub key
+
+    RtlInitUnicodeString(&uStr, (PWSTR) DEVICE_SUBKEY);
+
+    InitializeObjectAttributes(&oa, &uStr, OBJ_CASE_INSENSITIVE, hKey,
+                                (PSECURITY_DESCRIPTOR)NULL);
+
+    s = ZwCreateKey(Key, KEY_ALL_ACCESS, &oa, 0, NULL, REG_OPTION_VOLATILE,
+                    NULL);
+
+    ZwClose(hKey);
+
+    return s;
+}
+#endif
+
+
+NTSTATUS STDCALL EnumDeviceKeys(
+    IN PUNICODE_STRING RegistryPath,
+    IN PWSTR SubKey,
+    IN PREGISTRY_CALLBACK_ROUTINE Callback,
+    IN PVOID Context)
+/*
+    Description:
+        Enumerate the device subkeys in the driver's registry entry, and
+        call the specified callback routine for each device.
+
+    Parameters:
+        RegistryPath    The location of the registry entry
+        Subkey          The device's subkey
+        Callback        A routine called for each device
+        Context         ???
+
+    Return Value:
+        NT status STATUS_SUCCESS if successful
+*/
+{
+    NTSTATUS s;
+    OBJECT_ATTRIBUTES oa;
+    HANDLE hKey, hSubKey;
+    UNICODE_STRING SubkeyName;
+    ULONG i;
+
+    // Attempt to open the key
+
+    InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE,
+                                NULL, (PSECURITY_DESCRIPTOR)NULL);
+
+    s = ZwOpenKey(&hKey, KEY_READ, &oa);
+
+        TEST_STATUS(s); // debugging
+
+    if (! NT_SUCCESS(s))
+        return s;   // Problem
+
+    RtlInitUnicodeString(&SubkeyName, SubKey);
+
+    DPRINT("Subkey: %wZ\n", &SubkeyName);
+
+    InitializeObjectAttributes(&oa, &SubkeyName, OBJ_CASE_INSENSITIVE,
+                                hKey, (PSECURITY_DESCRIPTOR)NULL);
+
+    s = ZwOpenKey(&hSubKey, KEY_ENUMERATE_SUB_KEYS, &oa);
+
+    ZwClose(hKey);
+
+        TEST_STATUS(s); // debugging
+
+    if (! NT_SUCCESS(s))
+        return s;
+
+
+    // And now, the enumeration
+
+    for (i = 0;; i ++)
+    {
+        KEY_BASIC_INFORMATION Info;
+        PKEY_BASIC_INFORMATION pInfo;
+        ULONG ResultLength = 0;
+        ULONG Size = 0;
+        PWSTR Pos;
+        PWSTR Name;
+
+        // Find the length of the subkey data
+
+//        Info.NameLength = 0;    // TEMPORARY!
+
+        s = ZwEnumerateKey(hSubKey, i, KeyBasicInformation, &Info,
+                            sizeof(Info), &ResultLength);
+
+        if (s == STATUS_NO_MORE_ENTRIES)
+            break;
+
+        DPRINT("Found an entry, allocating memory...\n");
+
+//        Size = Info.NameLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
+        Size = ResultLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
+
+        DPRINT("Size is %d\n", Size);
+
+        pInfo = (PKEY_BASIC_INFORMATION) ExAllocatePool(PagedPool, Size);
+
+        if (pInfo == NULL)
+        {
+            DPRINT("INSUFFICIENT RESOURCES!\n");
+            s = STATUS_INSUFFICIENT_RESOURCES;
+            break;
+        }
+
+        DPRINT("Re-enumerating...\n");
+
+        s = ZwEnumerateKey(hSubKey, i, KeyBasicInformation, pInfo, Size,
+                            &ResultLength);
+
+//        TEST_STATUS(s); // debugging
+
+        if (! NT_SUCCESS(s))
+        {
+            ExFreePool((PVOID) pInfo);
+            s = STATUS_INTERNAL_ERROR;
+            break;
+        }
+
+        DPRINT("Allocating memory for name...\n");
+
+        Name = ExAllocatePool(PagedPool,
+                          RegistryPath->Length + sizeof(WCHAR) +
+                          SubkeyName.Length + sizeof(WCHAR) +
+                          pInfo->NameLength + sizeof(UNICODE_NULL));
+
+        if (Name == NULL)
+        {
+            DPRINT("INSUFFICIENT RESOURCES!");
+            ExFreePool((PVOID) pInfo);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        // Copy the key name
+        RtlCopyMemory((PVOID)Name, (PVOID)RegistryPath->Buffer, RegistryPath->Length);
+        Pos = Name + (RegistryPath->Length / sizeof(WCHAR));
+        Pos[0] = '\\';
+        Pos++;
+
+        // Copy the parameters sub key name
+        RtlCopyMemory((PVOID)Pos, (PVOID)SubKey, SubkeyName.Length);    //SubkeyName?
+        Pos += SubkeyName.Length / sizeof(WCHAR);
+        Pos[0] = '\\';
+        Pos ++;
+
+        // Copy the device sub key name
+        RtlCopyMemory((PVOID)Pos, (PVOID)pInfo->Name, pInfo->NameLength);
+        Pos += pInfo->NameLength / sizeof(WCHAR);
+        Pos[0] = UNICODE_NULL;
+
+        ExFreePool((PVOID)pInfo);
+
+        DPRINT("Calling callback...\n");
+
+        s = (*Callback)(Name, Context);
+
+        if (! NT_SUCCESS(s))
+        {   DPRINT("Callback FAILED\n");
+            break;}
+    }
+
+    ZwClose(hSubKey);
+
+    DPRINT("%d device registry keys found\n", i);
+
+    if ((i == 0) && (s == STATUS_NO_MORE_ENTRIES))
+        return STATUS_DEVICE_CONFIGURATION_ERROR;
+
+    return s == STATUS_NO_MORE_ENTRIES ? STATUS_SUCCESS : s;
+}
+
+
+
+NTSTATUS STDCALL LoadSettings(
+    IN  PWSTR ValueName,
+    IN  ULONG ValueType,
+    IN  PVOID ValueData,
+    IN  ULONG ValueLength,
+    IN  PVOID Context,
+    IN  PVOID EntryContext)
+/*
+    Description:
+        Read the settings for a particular device
+
+    Parameters:
+        ValueName       The value to read from the registry
+        ValueType       ?
+        ValueData       ?
+        ValueLength     ?
+        Context         The configuration structure to write to
+        EntryContext    ?
+
+    Return Value:
+        NT status STATUS_SUCCESS if successful
+*/
+{
+    PDEVICE_EXTENSION DeviceInfo = Context;
+
+    if (ValueType == REG_DWORD)
+    {
+        if (! _wcsicmp(ValueName, REGISTRY_PORT))
+        {
+            DeviceInfo->Port = *(PULONG) ValueData;
+            DPRINT("Registry port = 0x%x\n", DeviceInfo->Port);
+        }
+
+        // More to come... (config.c)
+    }
+
+    else
+    {
+        // ?
+    }
+
+    return STATUS_SUCCESS;
+}
+
+
+#if 0
+static NTSTATUS SaveSettings(
+    IN  PWSTR RegistryPath,
+    IN  ULONG Port,
+    IN  ULONG IRQ,
+    IN  ULONG DMA)
+/*
+    Description:
+        Saves the settings for a particular device
+
+    Parameters:
+        RegistryPath    Where to save the settings to
+        Port            The device's port number
+        IRQ             The device's interrupt number
+        DMA             The device's DMA channel
+
+    Return Value:
+        NT status STATUS_SUCCESS if successful
+*/
+{
+//    NTSTATUS s;
+
+    DPRINT("SaveSettings() unimplemented\n");
+
+//    UNIMPLEMENTED;
+
+    return STATUS_SUCCESS;
+}
+#endif
+

Added: trunk/reactos/drivers/multimedia/audio/mpu401_nt4/test.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/multimedia/audio/mpu401_nt4/test.c?rev=27485&view=auto
==============================================================================
--- trunk/reactos/drivers/multimedia/audio/mpu401_nt4/test.c (added)
+++ trunk/reactos/drivers/multimedia/audio/mpu401_nt4/test.c Sun Jul  8 20:07:01 2007
@@ -1,0 +1,70 @@
+#include <stdio.h>
+#include <windows.h>
+#include <ntddk.h>
+#include "mpu401.h"
+
+int main()
+{
+//    NTSTATUS s;
+//    PHANDLE Handle;
+//    PIO_STATUS_BLOCK Status;
+    DWORD BytesReturned;
+    BYTE Test[3]; // Will store MIDI data
+    BYTE Notes[] = {50, 52, 54, 55, 57, 59, 61};
+    HANDLE Device;
+    UINT Note;
+    UINT Junk;
+
+    printf("Test program for MPU401 driver\n");
+
+    Device = CreateFile("\\\\.\\MPU401_Out_0", GENERIC_READ | GENERIC_WRITE,
+                        FILE_SHARE_READ | FILE_SHARE_WRITE,
+                        NULL,
+                        OPEN_EXISTING,
+                        FILE_FLAG_NO_BUFFERING,
+                        NULL);
+
+    if (Device == INVALID_HANDLE_VALUE)
+    {
+        printf("Device is busy or could not be found.\n");
+        return -1;
+    }
+
+    printf("Device is open, let's play some music...\n");
+
+        Test[0] = 0x90;
+        Test[2] = 0x7f;
+
+    for (Note = 0; Note < sizeof(Notes); Note ++)
+    {
+        Test[1] = Notes[Note];
+
+    DeviceIoControl(
+        Device,
+        IOCTL_MIDI_PLAY,
+        &Test,
+        sizeof(Test),
+        NULL,
+        0,
+        &BytesReturned,
+        NULL
+        );
+
+        for (Junk = 0; Junk < 100000; Junk ++);   // Pause
+    }
+
+
+/*    s = IoCreateFile(Handle, GENERIC_READ | GENERIC_WRITE,
+                     OBJ_KERNEL_HANDLE,
+                     Status,
+                     0,
+                     FILE_SHARE_READ | FILE_SHARE_WRITE,
+                     FILE_OPEN,
+                     FILE_NON_DIRECTORY_FILE,
+                     NULL,
+                     0,
+                     CreateFileTypeNone,
+                     NULL,
+                     0);
+*/
+}




More information about the Ros-diffs mailing list