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 }
190