xref: /reactos/base/services/audiosrv/main.c (revision 4561998a)
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