Set service to manual start, and implemented a quick debug-logging

solution. ReactOS does not currently have RegisterDeviceNotification
implemented so if this function fails the audio service will still run
but won't receive plug and play event notifications (this is a temporary 
hack.)
Service now starts but won't find any devices (we don't have any yet!)


svn path=/trunk/; revision=29108
This commit is contained in:
Andrew Greenwood 2007-09-19 16:54:25 +00:00
parent 31163f4d3b
commit 4ee8a37af5
9 changed files with 122 additions and 8 deletions

View file

@ -61,4 +61,9 @@ HandleDeviceEvent(
DWORD dwEventType, DWORD dwEventType,
LPVOID lpEventData); LPVOID lpEventData);
/* Debugging */
void logmsg(char* string, ...);
#endif #endif

View file

@ -14,5 +14,6 @@ installname="audiosrv.exe" allowwarnings="true">
<file>pnp_list_manager.c</file> <file>pnp_list_manager.c</file>
<file>pnp_list_lock.c</file> <file>pnp_list_lock.c</file>
<file>pnp.c</file> <file>pnp.c</file>
<file>debug.c</file>
<file>audiosrv.rc</file> <file>audiosrv.rc</file>
</module> </module>

View file

@ -10,6 +10,9 @@ have any impact on functionality.
AudioSrv on Windows creates a mapped file at: AudioSrv on Windows creates a mapped file at:
Global\mmGlobalPnpInfo Global\mmGlobalPnpInfo
The ReactOS audio device list lives at:
Global\AudioDeviceList
This file appears to contain a list of devices that WinMM accesses and This file appears to contain a list of devices that WinMM accesses and
subsequently passes to wdmaud.drv subsequently passes to wdmaud.drv
@ -32,7 +35,39 @@ relevant audio devices, and also let AudioSrv in Windows do this. Then
it should be possible to create a small application that imitates it should be possible to create a small application that imitates
WinMM's actions :) WinMM's actions :)
So far, it doesn't do much... Watch this space!
Current Status
==============
AudioSrv registers for device notifications and obtains a list of the
current audio devices in the system (devices registered against the
KSCATEGORY_AUDIO interface).
ReactOS does not currently have RegisterDeviceNotification implemented,
so for the moment this service considers the failure of this API call
to be non-fatal and will proceed without device event notification. This
behaviour will be amended in a future revision (ie once this API call
is implemented!)
Testing the Service
===================
The service can be installed on Windows XP (possibly also Vista) like so:
sc create RosAudioSrv <path to audiosrv.exe>
net start RosAudioSrv
...and can be removed like so:
net stop RosAudioSrv
sc delete RosAudioSrv
You can view a list of the currently available devices (device list is
identical to the one offered by Windows' own AudioSrv) by running
my READER.EXE test utility, available in the following package:
http://stuff.silverblade.co.uk/reactos/sharedlist.tar.gz
That's all for now, folks ;)
Andrew Greenwood Andrew Greenwood

View file

@ -0,0 +1,19 @@
/* Service debugging (simply logs to a file) */
#include <stdio.h>
#include <stdarg.h>
void logmsg(char* string, ...)
{
va_list args;
FILE* debug_file = fopen("c:\\audiosrv-debug.txt", "a");
va_start(args, string);
vfprintf(debug_file, string, args);
va_end(args);
fclose(debug_file);
}

View file

@ -35,13 +35,19 @@ ServiceControlHandler(
{ {
case SERVICE_CONTROL_INTERROGATE : case SERVICE_CONTROL_INTERROGATE :
{ {
logmsg("* Interrogation\n");
return NO_ERROR; return NO_ERROR;
} }
case SERVICE_CONTROL_STOP : case SERVICE_CONTROL_STOP :
case SERVICE_CONTROL_SHUTDOWN : case SERVICE_CONTROL_SHUTDOWN :
{ {
logmsg("* Service Stop/Shutdown request received\n");
logmsg("Unregistering device notifications\n");
UnregisterDeviceNotifications(); UnregisterDeviceNotifications();
logmsg("Destroying audio device list\n");
DestroyAudioDeviceList(); DestroyAudioDeviceList();
service_status.dwCurrentState = SERVICE_STOP_PENDING; service_status.dwCurrentState = SERVICE_STOP_PENDING;
@ -52,11 +58,14 @@ ServiceControlHandler(
SetServiceStatus(service_status_handle, &service_status); SetServiceStatus(service_status_handle, &service_status);
logmsg("* Service stopped\n");
return NO_ERROR; return NO_ERROR;
} }
case SERVICE_CONTROL_DEVICEEVENT : case SERVICE_CONTROL_DEVICEEVENT :
{ {
logmsg("* Device Event\n");
return HandleDeviceEvent(dwEventType, lpEventData); return HandleDeviceEvent(dwEventType, lpEventData);
} }
@ -70,10 +79,15 @@ ServiceControlHandler(
VOID CALLBACK VOID CALLBACK
ServiceMain(DWORD argc, char** argv) ServiceMain(DWORD argc, char** argv)
{ {
logmsg("* Service starting\n");
logmsg("Registering service control handler...\n");
service_status_handle = RegisterServiceCtrlHandlerEx(SERVICE_NAME, service_status_handle = RegisterServiceCtrlHandlerEx(SERVICE_NAME,
ServiceControlHandler, ServiceControlHandler,
NULL); NULL);
logmsg("Service status handle %d\n", service_status_handle);
/* TODO: Deal with errors */
/* Set these to defaults */ /* Set these to defaults */
service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
service_status.dwServiceSpecificExitCode = 0; service_status.dwServiceSpecificExitCode = 0;
@ -86,29 +100,38 @@ ServiceMain(DWORD argc, char** argv)
service_status.dwCurrentState = SERVICE_START_PENDING; service_status.dwCurrentState = SERVICE_START_PENDING;
SetServiceStatus(service_status_handle, &service_status); SetServiceStatus(service_status_handle, &service_status);
logmsg("Creating audio device list\n");
/* This creates the audio device list and mutex */ /* This creates the audio device list and mutex */
if ( ! CreateAudioDeviceList(AUDIO_LIST_MAX_SIZE) ) if ( ! CreateAudioDeviceList(AUDIO_LIST_MAX_SIZE) )
{ {
logmsg("Failed to create audio device list\n");
service_status.dwCurrentState = SERVICE_STOPPED; service_status.dwCurrentState = SERVICE_STOPPED;
service_status.dwWin32ExitCode = -1; service_status.dwWin32ExitCode = -1;
SetServiceStatus(service_status_handle, &service_status); SetServiceStatus(service_status_handle, &service_status);
return; return;
} }
logmsg("Registering for device notifications\n");
/* We want to know when devices are added/removed */ /* We want to know when devices are added/removed */
if ( ! RegisterForDeviceNotifications() ) if ( ! RegisterForDeviceNotifications() )
{ {
/* FIXME: This is not fatal at present as ROS does not support this */
logmsg("Failed to register for device notifications\n");
/*
DestroyAudioDeviceList(); DestroyAudioDeviceList();
service_status.dwCurrentState = SERVICE_STOPPED; service_status.dwCurrentState = SERVICE_STOPPED;
service_status.dwWin32ExitCode = -1; service_status.dwWin32ExitCode = -1;
SetServiceStatus(service_status_handle, &service_status); SetServiceStatus(service_status_handle, &service_status);
return; return;
*/
} }
logmsg("Processing existing devices\n");
/* Now find any devices that already exist on the system */ /* Now find any devices that already exist on the system */
if ( ! ProcessExistingDevices() ) if ( ! ProcessExistingDevices() )
{ {
logmsg("Could not process existing devices\n");
UnregisterDeviceNotifications(); UnregisterDeviceNotifications();
DestroyAudioDeviceList(); DestroyAudioDeviceList();
@ -118,6 +141,7 @@ ServiceMain(DWORD argc, char** argv)
return; return;
} }
logmsg("* Service started");
/* Tell SCM we are now running, and we may be stopped */ /* Tell SCM we are now running, and we may be stopped */
service_status.dwCurrentState = SERVICE_RUNNING; service_status.dwCurrentState = SERVICE_RUNNING;
service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP; service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
@ -126,6 +150,7 @@ ServiceMain(DWORD argc, char** argv)
int main() int main()
{ {
logmsg("Audio Service main()\n");
StartServiceCtrlDispatcher(service_table); StartServiceCtrlDispatcher(service_table);
return 0; return 0;
} }

View file

@ -127,7 +127,6 @@ RegisterForDeviceNotifications()
const GUID wdmaud_guid = {STATIC_KSCATEGORY_AUDIO}; const GUID wdmaud_guid = {STATIC_KSCATEGORY_AUDIO};
/* FIXME: This currently lists ALL device interfaces... */
ZeroMemory(&notification_filter, sizeof(notification_filter)); ZeroMemory(&notification_filter, sizeof(notification_filter));
notification_filter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); notification_filter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
notification_filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; notification_filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
@ -140,6 +139,11 @@ RegisterForDeviceNotifications()
/* | /* |
DEVICE_NOTIFY_ALL_INTERFACE_CLASSES*/); DEVICE_NOTIFY_ALL_INTERFACE_CLASSES*/);
if ( ! device_notification_handle )
{
logmsg("RegisterDeviceNotification() failed with error %d\n", GetLastError());
}
return ( device_notification_handle != NULL ); return ( device_notification_handle != NULL );
} }
@ -152,7 +156,12 @@ RegisterForDeviceNotifications()
VOID UnregisterDeviceNotifications() VOID UnregisterDeviceNotifications()
{ {
/* TODO -- NOT IMPLEMENTED! */ /* TODO -- NOT IMPLEMENTED! */
device_notification_handle = NULL;
if ( device_notification_handle )
{
/* TODO */
device_notification_handle = NULL;
}
} }

View file

@ -8,6 +8,7 @@
#include <assert.h> #include <assert.h>
#include <audiosrv/audiosrv.h> #include <audiosrv/audiosrv.h>
#include "audiosrv.h"
/* /*
@ -27,7 +28,10 @@ CreateDeviceDescriptor(WCHAR* path, BOOL is_enabled)
device = malloc(size); device = malloc(size);
if ( ! device ) if ( ! device )
{
log("Failed to create a device descriptor (malloc fail)\n");
return NULL; return NULL;
}
device->enabled = is_enabled; device->enabled = is_enabled;
memcpy(device->path, path, path_length); memcpy(device->path, path, path_length);
@ -72,9 +76,7 @@ AppendAudioDeviceToList(PnP_AudioDevice* device)
/* We DON'T want to overshoot the end of the buffer! */ /* We DON'T want to overshoot the end of the buffer! */
if ( audio_device_list->size + device_info_size > audio_device_list->max_size ) if ( audio_device_list->size + device_info_size > audio_device_list->max_size )
{ {
/* printf("max_size would be exceeded! Failing...\n");
printf("max_size would be exceeded! failing\n");
*/
return FALSE; return FALSE;
} }
@ -89,6 +91,8 @@ AppendAudioDeviceToList(PnP_AudioDevice* device)
UnlockAudioDeviceList(); UnlockAudioDeviceList();
log("Device added to list\n");
return TRUE; return TRUE;
} }
@ -108,6 +112,7 @@ CreateAudioDeviceList(DWORD max_size)
turning up before we're ready... */ turning up before we're ready... */
LockAudioDeviceList(); LockAudioDeviceList();
log("Creating file mapping\n");
/* Expose our device list to the world */ /* Expose our device list to the world */
device_list_file = CreateFileMapping(INVALID_HANDLE_VALUE, device_list_file = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL, NULL,
@ -118,7 +123,7 @@ CreateAudioDeviceList(DWORD max_size)
if ( ! device_list_file ) if ( ! device_list_file )
{ {
/*printf("Creation of audio device list FAILED!\n");*/ log("Creation of audio device list failed (err %d)\n", GetLastError());
UnlockAudioDeviceList(); UnlockAudioDeviceList();
KillAudioDeviceListLock(); KillAudioDeviceListLock();
@ -126,6 +131,7 @@ CreateAudioDeviceList(DWORD max_size)
return FALSE; return FALSE;
} }
log("Mapping view of file\n");
/* Of course, we'll need to access the list ourselves */ /* Of course, we'll need to access the list ourselves */
audio_device_list = MapViewOfFile(device_list_file, audio_device_list = MapViewOfFile(device_list_file,
FILE_MAP_WRITE, FILE_MAP_WRITE,
@ -135,7 +141,7 @@ CreateAudioDeviceList(DWORD max_size)
if ( ! audio_device_list ) if ( ! audio_device_list )
{ {
/*printf("MapViewOfFile FAILED\n");*/ log("MapViewOfFile FAILED (err %d)\n", GetLastError());
CloseHandle(device_list_file); CloseHandle(device_list_file);
device_list_file = NULL; device_list_file = NULL;
@ -156,12 +162,16 @@ CreateAudioDeviceList(DWORD max_size)
UnlockAudioDeviceList(); UnlockAudioDeviceList();
log("Device list created\n");
return TRUE; return TRUE;
} }
VOID VOID
DestroyAudioDeviceList() DestroyAudioDeviceList()
{ {
log("Destroying device list\n");
LockAudioDeviceList(); LockAudioDeviceList();
/*printf("Unmapping view\n");*/ /*printf("Unmapping view\n");*/

View file

@ -480,6 +480,15 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Atapi","Start",0x00010001,0x00000000
HKLM,"SYSTEM\CurrentControlSet\Services\Atapi","Type",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Atapi","Type",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\Atapi","Tag",0x00010001,0x00000010 HKLM,"SYSTEM\CurrentControlSet\Services\Atapi","Tag",0x00010001,0x00000010
; Audio Service
HKLM,"SYSTEM\CurrentControlSet\Services\AudioSrv","DisplayName",0x00000000,"Audio Service"
HKLM,"SYSTEM\CurrentControlSet\Services\AudioSrv","Description",0x00000000,"Provides audio facilities to applications"
HKLM,"SYSTEM\CurrentControlSet\Services\AudioSrv","ErrorControl",0x00010001,0x00000000
HKLM,"SYSTEM\CurrentControlSet\Services\AudioSrv","Group",0x00000000,"Audio"
HKLM,"SYSTEM\CurrentControlSet\Services\AudioSrv","ImagePath",0x00020000,"%SystemRoot%\system32\audiosrv.exe"
HKLM,"SYSTEM\CurrentControlSet\Services\AudioSrv","Start",0x00010001,0x00000003
HKLM,"SYSTEM\CurrentControlSet\Services\AudioSrv","Type",0x00010001,0x00000010
; BusLogic 958 miniport driver ; BusLogic 958 miniport driver
HKLM,"SYSTEM\CurrentControlSet\Services\BusLogic","ErrorControl",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\BusLogic","ErrorControl",0x00010001,0x00000000
HKLM,"SYSTEM\CurrentControlSet\Services\BusLogic","Group",0x00000000,"SCSI Miniport" HKLM,"SYSTEM\CurrentControlSet\Services\BusLogic","Group",0x00000000,"SCSI Miniport"

View file

@ -75,6 +75,7 @@ base\services\rpcss\rpcss.exe 1
base\services\tcpsvcs\tcpsvcs.exe 1 base\services\tcpsvcs\tcpsvcs.exe 1
base\services\tcpsvcs\quotes 5 base\services\tcpsvcs\quotes 5
base\services\umpnpmgr\umpnpmgr.exe 1 base\services\umpnpmgr\umpnpmgr.exe 1
base\services\audiosrv\audiosrv.exe 1
base\setup\setup\setup.exe 1 base\setup\setup\setup.exe 1
base\setup\vmwinst\vmwinst.exe 1 base\setup\vmwinst\vmwinst.exe 1