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