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     if (! device)
27     {
28         logmsg("Failed to create a device descriptor (malloc fail)\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
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 /*
68     printf("list size is %d\n", audio_device_list->size);
69     printf("device info size is %d bytes\n", device_info_size);
70 */
71 
72     /* We DON'T want to overshoot the end of the buffer! */
73     if (audio_device_list->size + device_info_size > audio_device_list->max_size)
74     {
75         /*printf("max_size would be exceeded! Failing...\n");*/
76 
77         UnlockAudioDeviceList();
78 
79         return FALSE;
80     }
81 
82     /* Commit the device descriptor to the list */
83     memcpy((char*)audio_device_list + audio_device_list->size,
84            device,
85            device_info_size);
86 
87     /* Update the header */
88     audio_device_list->device_count ++;
89     audio_device_list->size += device_info_size;
90 
91     UnlockAudioDeviceList();
92 
93     logmsg("Device added to list\n");
94 
95     return TRUE;
96 }
97 
98 BOOL
99 CreateAudioDeviceList(DWORD max_size)
100 {
101 /*    printf("Initializing memory device list lock\n");*/
102 
103     if (!InitializeAudioDeviceListLock())
104     {
105         /*printf("Failed!\n");*/
106         return FALSE;
107     }
108 
109     /* Preliminary locking - the list memory will likely be a big
110        buffer of gibberish at this point so we don't want anyone
111        turning up before we're ready... */
112     LockAudioDeviceList();
113 
114     logmsg("Creating file mapping\n");
115     /* Expose our device list to the world */
116     device_list_file = CreateFileMappingW(INVALID_HANDLE_VALUE,
117                                           NULL,
118                                           PAGE_READWRITE,
119                                           0,
120                                           max_size,
121                                           AUDIO_LIST_NAME);
122     if (!device_list_file)
123     {
124         logmsg("Creation of audio device list failed (err %d)\n", GetLastError());
125 
126         UnlockAudioDeviceList();
127         KillAudioDeviceListLock();
128 
129         return FALSE;
130     }
131 
132     logmsg("Mapping view of file\n");
133     /* Of course, we'll need to access the list ourselves */
134     audio_device_list = MapViewOfFile(device_list_file,
135                                       FILE_MAP_WRITE,
136                                       0,
137                                       0,
138                                       max_size);
139     if (!audio_device_list)
140     {
141         logmsg("MapViewOfFile FAILED (err %d)\n", GetLastError());
142 
143         CloseHandle(device_list_file);
144         device_list_file = NULL;
145 
146         UnlockAudioDeviceList();
147         KillAudioDeviceListLock();
148 
149         return FALSE;
150     }
151 
152     /* Clear the mem to avoid any random stray data */
153     memset(audio_device_list, 0, max_size);
154 
155     /* Don't want devices to overwrite the list! */
156     audio_device_list->size = sizeof(PnP_AudioHeader);
157     audio_device_list->max_size = max_size;
158     audio_device_list->device_count = 0;
159 
160     UnlockAudioDeviceList();
161 
162     logmsg("Device list created\n");
163 
164     return TRUE;
165 }
166 
167 VOID
168 DestroyAudioDeviceList(VOID)
169 {
170     logmsg("Destroying device list\n");
171 
172     LockAudioDeviceList();
173 
174     /*printf("Unmapping view\n");*/
175     UnmapViewOfFile(audio_device_list);
176     audio_device_list = NULL;
177 
178     /*printf("Closing memory mapped file\n");*/
179     CloseHandle(device_list_file);
180     device_list_file = NULL;
181 
182     UnlockAudioDeviceList();
183 
184     /*printf("Killing devlist lock\n");*/
185     KillAudioDeviceListLock();
186 }
187