diff --git a/reactos/base/services/audiosrv/audiosrv.rbuild b/reactos/base/services/audiosrv/audiosrv.rbuild
new file mode 100644
index 00000000000..07e5e40d505
--- /dev/null
+++ b/reactos/base/services/audiosrv/audiosrv.rbuild
@@ -0,0 +1,10 @@
+
+ .
+
+
+ 0x0501
+ kernel32
+ advapi32
+ main.c
+ audiosrv.rc
+
diff --git a/reactos/base/services/audiosrv/audiosrv.rc b/reactos/base/services/audiosrv/audiosrv.rc
new file mode 100644
index 00000000000..e3637bcf619
--- /dev/null
+++ b/reactos/base/services/audiosrv/audiosrv.rc
@@ -0,0 +1,4 @@
+#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Audio Service"
+#define REACTOS_STR_INTERNAL_NAME "audiosrv\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "audiosrv.dll\0"
+#include
diff --git a/reactos/base/services/audiosrv/audiosrv.txt b/reactos/base/services/audiosrv/audiosrv.txt
new file mode 100644
index 00000000000..978d768a9e4
--- /dev/null
+++ b/reactos/base/services/audiosrv/audiosrv.txt
@@ -0,0 +1,39 @@
+ReactOS Audio Service (audiosrv.exe)
+====================================
+
+This is intended to operate in a similar manner to how the Windows Audio
+Service does.
+
+NOTE: The service filename is audiosrv.dll on Windows XP. This shouldn't
+have any impact on functionality.
+
+AudioSrv on Windows creates a mapped file at:
+Global\mmGlobalPnpInfo
+
+This file appears to contain a list of devices that WinMM accesses and
+subsequently passes to wdmaud.drv
+
+It is not necessary to duplicate the exact structure of this mapped
+file, since it appears to only be used internally by Windows components.
+
+The ROS Audio Service (RosAudioSrv) is intended to be able to run
+alongside the Windows Audio Service on XP/Vista, so it should be
+possible to test in a "known working environment" ;)
+
+It will create a mutex, to:
+1) Allow synchronization when accessing the device list
+2) Provide a simple method of identifying if RosAudioSrv is running
+
+(It might be worth using an event to notify WinMM when things are
+happening?)
+
+The intention is to make RosAudioSrv receive PnP notifications for
+relevant audio devices, and also let AudioSrv in Windows do this. Then
+it should be possible to create a small application that imitates
+WinMM's actions :)
+
+So far, it doesn't do much... Watch this space!
+
+
+Andrew Greenwood
+September 2007
diff --git a/reactos/base/services/audiosrv/main.c b/reactos/base/services/audiosrv/main.c
new file mode 100644
index 00000000000..5139c902b80
--- /dev/null
+++ b/reactos/base/services/audiosrv/main.c
@@ -0,0 +1,117 @@
+/*
+ * PROJECT: ReactOS
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: base/services/audiosrv/main.c
+ * PURPOSE: Audio Service
+ * COPYRIGHT: Copyright 2007 Andrew Greenwood
+ */
+
+#include
+
+/* This is currently set to avoid conflicting service names in Windows! */
+#define SERVICE_NAME "RosAudioSrv"
+
+/* A named mutex is used for synchronizing access to the device list.
+ If this mutex doesn't exist, it means the audio service isn't running. */
+#define DEVICE_LIST_MUTEX_NAME "Global\\AudioDeviceListSync"
+
+/* ...and this is where the device list will be available */
+#define DEVICE_LIST_MAPPED_FILENAME "Global\\AudioDeviceList"
+
+
+
+/* Prototypes */
+
+VOID CALLBACK
+ServiceMain(DWORD argc, char** argv);
+
+VOID WINAPI
+ServiceControlHandler(DWORD request);
+
+
+/* Service table */
+SERVICE_TABLE_ENTRY service_table[2] =
+{
+ { "AudioSrv", (LPSERVICE_MAIN_FUNCTION) ServiceMain },
+ { NULL, NULL }
+};
+
+SERVICE_STATUS_HANDLE service_status_handle;
+SERVICE_STATUS service_status;
+
+/* Synchronization of access to the event list */
+HANDLE device_list_mutex = INVALID_HANDLE_VALUE;
+
+
+/* Implementation */
+
+VOID WINAPI
+ServiceControlHandler(DWORD request)
+{
+ switch ( request )
+ {
+ case SERVICE_CONTROL_STOP :
+ case SERVICE_CONTROL_SHUTDOWN :
+ {
+ service_status.dwCurrentState = SERVICE_STOP_PENDING;
+ SetServiceStatus(service_status_handle, &service_status);
+
+ CloseHandle(device_list_mutex);
+
+ service_status.dwWin32ExitCode = 0;
+ service_status.dwCurrentState = SERVICE_STOPPED;
+
+ SetServiceStatus(service_status_handle, &service_status);
+
+ return;
+ }
+
+
+ default :
+ break;
+ };
+
+ SetServiceStatus(service_status_handle, &service_status);
+}
+
+VOID CALLBACK
+ServiceMain(DWORD argc, char** argv)
+{
+ service_status_handle = RegisterServiceCtrlHandler(SERVICE_NAME,
+ ServiceControlHandler);
+
+ /* Set these to defaults */
+ service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ service_status.dwServiceSpecificExitCode = 0;
+ service_status.dwWin32ExitCode = NO_ERROR;
+ service_status.dwWaitHint = 0;
+ service_status.dwControlsAccepted = 0;
+ service_status.dwCheckPoint = 0;
+
+ /* Tell SCM we're starting */
+ service_status.dwCurrentState = SERVICE_START_PENDING;
+ SetServiceStatus(service_status_handle, &service_status);
+
+ /* We should create the mapped section here along with the mutex to
+ sync access to the device list... */
+
+ device_list_mutex = CreateMutex(NULL, FALSE, DEVICE_LIST_MUTEX_NAME);
+
+ if ( ! device_list_mutex)
+ {
+ service_status.dwCurrentState = SERVICE_STOPPED;
+ service_status.dwWin32ExitCode = -1; // ok?
+ SetServiceStatus(service_status_handle, &service_status);
+ return;
+ }
+
+ /* Tell SCM we are now running, and we may be stopped */
+ service_status.dwCurrentState = SERVICE_RUNNING;
+ service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+ SetServiceStatus(service_status_handle, &service_status);
+}
+
+int main()
+{
+ StartServiceCtrlDispatcher(service_table);
+}
diff --git a/reactos/base/services/services.rbuild b/reactos/base/services/services.rbuild
index 56544bec510..890176ac9b9 100644
--- a/reactos/base/services/services.rbuild
+++ b/reactos/base/services/services.rbuild
@@ -1,6 +1,9 @@
+
+
+