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