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 @@ + + +