Revert "[SHELL32] SHChangeNotify: Use tree for CDirectoryList (#6784)" (#6800)
[reactos.git] / base / services / audiosrv / main.c
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 }