xref: /reactos/base/services/audiosrv/main.c (revision 682f85ad)
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(VOID)
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     InitializeFakeDevice();
136 
137     logmsg("Processing existing devices\n");
138     /* Now find any devices that already exist on the system */
139     if (!ProcessExistingDevices())
140     {
141         logmsg("Could not process existing devices\n");
142         UnregisterDeviceNotifications();
143         DestroyAudioDeviceList();
144 
145         service_status.dwCurrentState = SERVICE_STOPPED;
146         service_status.dwWin32ExitCode = -1;
147         SetServiceStatus(service_status_handle, &service_status);
148         return;
149     }
150 
151     logmsg("* Service started\n");
152     /* Tell SCM we are now running, and we may be stopped */
153     service_status.dwCurrentState = SERVICE_RUNNING;
154     service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
155     SetServiceStatus(service_status_handle, &service_status);
156 }
157 
158 int wmain(VOID)
159 {
160     SERVICE_TABLE_ENTRYW service_table[] =
161     {
162         { SERVICE_NAME, (LPSERVICE_MAIN_FUNCTIONW) ServiceMain },
163         { NULL, NULL }
164     };
165 
166     logmsg("Audio Service main()\n");
167     if (!StartServiceCtrlDispatcherW(service_table))
168         logmsg("StartServiceCtrlDispatcher failed\n");
169 
170     return 0;
171 }
172