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