1 /* 2 * PROJECT: ReactOS 3 * LICENSE: GPL - See COPYING in the top level directory 4 * PURPOSE: Audio Service 5 * COPYRIGHT: Copyright 2007 Andrew Greenwood 6 */ 7 8 #include "audiosrv.h" 9 10 #define NDEBUG 11 #include <debug.h> 12 13 SERVICE_STATUS_HANDLE service_status_handle; 14 SERVICE_STATUS service_status; 15 16 17 /* This is for testing only! */ 18 VOID 19 InitializeFakeDevice(VOID) 20 { 21 PnP_AudioDevice* list_node; 22 23 list_node = CreateDeviceDescriptor(L"ThisDeviceDoesNotReallyExist", TRUE); 24 AppendAudioDeviceToList(list_node); 25 DestroyDeviceDescriptor(list_node); 26 } 27 28 DWORD WINAPI 29 ServiceControlHandler( 30 DWORD dwControl, 31 DWORD dwEventType, 32 LPVOID lpEventData, 33 LPVOID lpContext) 34 { 35 switch (dwControl) 36 { 37 case SERVICE_CONTROL_INTERROGATE : 38 { 39 DPRINT("* Interrogation\n"); 40 return NO_ERROR; 41 } 42 43 case SERVICE_CONTROL_STOP : 44 case SERVICE_CONTROL_SHUTDOWN : 45 { 46 DPRINT("* Service Stop/Shutdown request received\n"); 47 48 DPRINT("Unregistering device notifications\n"); 49 UnregisterDeviceNotifications(); 50 51 DPRINT("Destroying audio device list\n"); 52 DestroyAudioDeviceList(); 53 54 service_status.dwCurrentState = SERVICE_STOP_PENDING; 55 SetServiceStatus(service_status_handle, &service_status); 56 57 service_status.dwWin32ExitCode = 0; 58 service_status.dwCurrentState = SERVICE_STOPPED; 59 60 SetServiceStatus(service_status_handle, &service_status); 61 62 DPRINT("* Service stopped\n"); 63 64 return NO_ERROR; 65 } 66 67 case SERVICE_CONTROL_DEVICEEVENT : 68 { 69 DPRINT("* Device Event\n"); 70 return HandleDeviceEvent(dwEventType, lpEventData); 71 } 72 73 default : 74 return ERROR_CALL_NOT_IMPLEMENTED; 75 }; 76 77 /*SetServiceStatus(service_status_handle, &service_status);*/ 78 } 79 80 VOID CALLBACK 81 ServiceMain(DWORD argc, LPWSTR argv) 82 { 83 DPRINT("* Service starting\n"); 84 DPRINT("Registering service control handler\n"); 85 service_status_handle = RegisterServiceCtrlHandlerExW(SERVICE_NAME, 86 ServiceControlHandler, 87 NULL); 88 89 DPRINT("Service status handle %d\n", service_status_handle); 90 if (!service_status_handle) 91 { 92 DPRINT("Failed to register service control handler\n"); 93 /* FIXME - we should fail */ 94 } 95 96 /* Set these to defaults */ 97 service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 98 service_status.dwServiceSpecificExitCode = 0; 99 service_status.dwWin32ExitCode = NO_ERROR; 100 service_status.dwWaitHint = 0; 101 service_status.dwControlsAccepted = 0; 102 service_status.dwCheckPoint = 0; 103 104 /* Tell SCM we're starting */ 105 service_status.dwCurrentState = SERVICE_START_PENDING; 106 SetServiceStatus(service_status_handle, &service_status); 107 108 DPRINT("Creating audio device list\n"); 109 /* This creates the audio device list and mutex */ 110 if (!CreateAudioDeviceList(AUDIO_LIST_MAX_SIZE)) 111 { 112 DPRINT("Failed to create audio device list\n"); 113 service_status.dwCurrentState = SERVICE_STOPPED; 114 service_status.dwWin32ExitCode = -1; 115 SetServiceStatus(service_status_handle, &service_status); 116 return; 117 } 118 119 DPRINT("Registering for device notifications\n"); 120 /* We want to know when devices are added/removed */ 121 if (!RegisterForDeviceNotifications()) 122 { 123 /* FIXME: This is not fatal at present as ROS does not support this */ 124 DPRINT("Failed to register for device notifications\n"); 125 /* 126 DestroyAudioDeviceList(); 127 128 service_status.dwCurrentState = SERVICE_STOPPED; 129 service_status.dwWin32ExitCode = -1; 130 SetServiceStatus(service_status_handle, &service_status); 131 return; 132 */ 133 } 134 /* start system audio services */ 135 StartSystemAudioServices(); 136 137 InitializeFakeDevice(); 138 139 DPRINT("Processing existing devices\n"); 140 /* Now find any devices that already exist on the system */ 141 if (!ProcessExistingDevices()) 142 { 143 DPRINT("Could not process existing devices\n"); 144 UnregisterDeviceNotifications(); 145 DestroyAudioDeviceList(); 146 147 service_status.dwCurrentState = SERVICE_STOPPED; 148 service_status.dwWin32ExitCode = -1; 149 SetServiceStatus(service_status_handle, &service_status); 150 return; 151 } 152 153 DPRINT("* Service started\n"); 154 /* Tell SCM we are now running, and we may be stopped */ 155 service_status.dwCurrentState = SERVICE_RUNNING; 156 service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP; 157 SetServiceStatus(service_status_handle, &service_status); 158 } 159 160 int wmain(VOID) 161 { 162 SERVICE_TABLE_ENTRYW service_table[] = 163 { 164 { SERVICE_NAME, (LPSERVICE_MAIN_FUNCTIONW) ServiceMain }, 165 { NULL, NULL } 166 }; 167 168 DPRINT("Audio Service main()\n"); 169 if (!StartServiceCtrlDispatcherW(service_table)) 170 DPRINT("StartServiceCtrlDispatcher failed\n"); 171 172 return 0; 173 } 174