* Sync up to trunk head (r65120).
[reactos.git] / base / services / audiosrv / main.c
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 }