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