1 /*
2 * PROJECT: ReactOS
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Audio Service List Manager
5 * COPYRIGHT: Copyright 2007 Andrew Greenwood
6 */
7
8 #include "audiosrv.h"
9
10 #define NDEBUG
11 #include <debug.h>
12
13 /*
14 Device descriptor
15 */
16
17 VOID*
CreateDeviceDescriptor(WCHAR * path,BOOL is_enabled)18 CreateDeviceDescriptor(WCHAR* path, BOOL is_enabled)
19 {
20 PnP_AudioDevice* device;
21
22 int path_length = WideStringSize(path);
23 int size = sizeof(PnP_AudioDevice) + path_length;
24
25 device = malloc(size);
26 if (! device)
27 {
28 DPRINT("Failed to malloc device descriptor\n");
29 return NULL;
30 }
31
32 device->enabled = is_enabled;
33 memcpy(device->path, path, path_length);
34
35 return device;
36 }
37
38
39 /*
40 Device list (manager-side)
41
42 The device list is stored in some shared-memory, with a named, global
43 mutex to provide a locking mechanism (to avoid it from being updated
44 whilst being read).
45 */
46
47 static HANDLE device_list_file = NULL;
48 static PnP_AudioHeader* audio_device_list = NULL;
49
50
51 /*
52 TODO: Detect duplicate entries and ignore them! (In case we receive
53 a PnP event for an existing device...)
54 */
55
56 BOOL
AppendAudioDeviceToList(PnP_AudioDevice * device)57 AppendAudioDeviceToList(PnP_AudioDevice* device)
58 {
59 int device_info_size;
60
61 /* Figure out the actual structure size */
62 device_info_size = sizeof(PnP_AudioDevice);
63 device_info_size += WideStringSize(device->path);
64
65 LockAudioDeviceList();
66
67 /* We DON'T want to overshoot the end of the buffer! */
68 if (audio_device_list->size + device_info_size > audio_device_list->max_size)
69 {
70 /*DPRINT("failed, max_size would be exceeded\n");*/
71
72 UnlockAudioDeviceList();
73
74 return FALSE;
75 }
76
77 /* Commit the device descriptor to the list */
78 memcpy((char*)audio_device_list + audio_device_list->size,
79 device,
80 device_info_size);
81
82 /* Update the header */
83 audio_device_list->device_count ++;
84 audio_device_list->size += device_info_size;
85
86 UnlockAudioDeviceList();
87
88 DPRINT("Device added to list\n");
89
90 return TRUE;
91 }
92
93 BOOL
CreateAudioDeviceList(DWORD max_size)94 CreateAudioDeviceList(DWORD max_size)
95 {
96 if (!InitializeAudioDeviceListLock())
97 {
98 /*DPRINT("Failed\n");*/
99 return FALSE;
100 }
101
102 /* Preliminary locking - the list memory will likely be a big
103 buffer of gibberish at this point so we don't want anyone
104 turning up before we're ready... */
105 LockAudioDeviceList();
106
107 DPRINT("Creating file mapping\n");
108 /* Expose our device list to the world */
109 device_list_file = CreateFileMappingW(INVALID_HANDLE_VALUE,
110 NULL,
111 PAGE_READWRITE,
112 0,
113 max_size,
114 AUDIO_LIST_NAME);
115 if (!device_list_file)
116 {
117 DPRINT("Creation of audio device list failed (err %d)\n", GetLastError());
118
119 UnlockAudioDeviceList();
120 KillAudioDeviceListLock();
121
122 return FALSE;
123 }
124
125 DPRINT("Mapping view of file\n");
126 /* Of course, we'll need to access the list ourselves */
127 audio_device_list = MapViewOfFile(device_list_file,
128 FILE_MAP_WRITE,
129 0,
130 0,
131 max_size);
132 if (!audio_device_list)
133 {
134 DPRINT("MapViewOfFile FAILED (err %d)\n", GetLastError());
135
136 CloseHandle(device_list_file);
137 device_list_file = NULL;
138
139 UnlockAudioDeviceList();
140 KillAudioDeviceListLock();
141
142 return FALSE;
143 }
144
145 /* Clear the mem to avoid any random stray data */
146 memset(audio_device_list, 0, max_size);
147
148 /* Don't want devices to overwrite the list! */
149 audio_device_list->size = sizeof(PnP_AudioHeader);
150 audio_device_list->max_size = max_size;
151 audio_device_list->device_count = 0;
152
153 UnlockAudioDeviceList();
154
155 DPRINT("Device list created\n");
156
157 return TRUE;
158 }
159
160 VOID
DestroyAudioDeviceList(VOID)161 DestroyAudioDeviceList(VOID)
162 {
163 DPRINT("Destroying device list\n");
164
165 LockAudioDeviceList();
166
167 /*DPRINT("Unmapping view\n");*/
168 UnmapViewOfFile(audio_device_list);
169 audio_device_list = NULL;
170
171 /*DPRINT("Closing memory mapped file\n");*/
172 CloseHandle(device_list_file);
173 device_list_file = NULL;
174
175 UnlockAudioDeviceList();
176
177 /*DPRINT("Killing devlist lock\n");*/
178 KillAudioDeviceListLock();
179 }
180