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