1 /*
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS Multimedia
5 * FILE: lib/mmdrv/utils.c
6 * PURPOSE: Multimedia User Mode Driver (utility functions)
7 * PROGRAMMER: Andrew Greenwood
8 * UPDATE HISTORY:
9 * Jan 30, 2004: Imported into ReactOS tree
10 */
11
12 #include "mmdrv.h"
13
14 #define NDEBUG
15 #include <debug.h>
16
17 typedef struct _DEVICE_LIST
18 {
19 struct _DEVICE_LIST *Next;
20 DWORD DeviceType;
21 ULONG CardIndex;
22 PVOID DeviceInstanceData;
23 ULONG DeviceInstanceDataSize;
24 WCHAR Name[1];
25 } DEVICE_LIST, *PDEVICE_LIST;
26
27 PDEVICE_LIST DeviceList;
28
29
TranslateStatus(void)30 DWORD TranslateStatus(void)
31 {
32 switch(GetLastError())
33 {
34 case NO_ERROR :
35 case ERROR_IO_PENDING :
36 return MMSYSERR_NOERROR;
37
38 case ERROR_BUSY :
39 return MMSYSERR_ALLOCATED;
40
41 case ERROR_NOT_SUPPORTED :
42 case ERROR_INVALID_FUNCTION :
43 return MMSYSERR_NOTSUPPORTED;
44
45 case ERROR_NOT_ENOUGH_MEMORY :
46 return MMSYSERR_NOMEM;
47
48 case ERROR_ACCESS_DENIED :
49 return MMSYSERR_BADDEVICEID;
50
51 case ERROR_INSUFFICIENT_BUFFER :
52 return MMSYSERR_INVALPARAM;
53
54 default :
55 return MMSYSERR_ERROR;
56 };
57 }
58
59
60
OpenDevice(UINT DeviceType,DWORD ID,PHANDLE pDeviceHandle,DWORD Access)61 MMRESULT OpenDevice(UINT DeviceType, DWORD ID, PHANDLE pDeviceHandle,
62 DWORD Access)
63 {
64 DPRINT("OpenDevice()\n");
65 WCHAR DeviceName[SOUND_MAX_DEVICE_NAME];
66 *pDeviceHandle = INVALID_HANDLE_VALUE;
67
68 if (ID > SOUND_MAX_DEVICES)
69 return MMSYSERR_BADDEVICEID;
70
71 switch(DeviceType)
72 {
73 case WaveOutDevice :
74 wsprintf(DeviceName, L"\\\\.%ls%d", WAVE_OUT_DEVICE_NAME_U + strlen("\\Device"), ID);
75 break;
76 case WaveInDevice :
77 wsprintf(DeviceName, L"\\\\.%ls%d", WAVE_IN_DEVICE_NAME_U + strlen("\\Device"), ID);
78 break;
79 case MidiOutDevice :
80 wsprintf(DeviceName, L"\\\\.%ls%d", MIDI_OUT_DEVICE_NAME_U + strlen("\\Device"), ID);
81 break;
82 case MidiInDevice :
83 wsprintf(DeviceName, L"\\\\.%ls%d", MIDI_IN_DEVICE_NAME_U + strlen("\\Device"), ID);
84 break;
85 case AuxDevice :
86 wsprintf(DeviceName, L"\\\\.%ls%d", AUX_DEVICE_NAME_U + strlen("\\Device"), ID);
87 break;
88 default :
89 DPRINT("No Auido Device Found");
90 return MMSYSERR_BADDEVICEID; /* Maybe we should change error code */
91 };
92
93 DPRINT("Attempting to open %S\n", DeviceName);
94
95 *pDeviceHandle = CreateFile(DeviceName, Access, FILE_SHARE_WRITE, NULL,
96 OPEN_EXISTING, Access != GENERIC_READ ? FILE_FLAG_OVERLAPPED : 0,
97 NULL);
98
99 DPRINT("DeviceHandle == 0x%x\n", (int)*pDeviceHandle);
100
101 if (pDeviceHandle == INVALID_HANDLE_VALUE)
102 return TranslateStatus();
103
104 return MMSYSERR_NOERROR;
105 }
106
107
108 // DEVICE LIST MANAGEMENT
109
110
AddDeviceToList(PDEVICE_LIST * pList,DWORD DeviceType,DWORD CardIndex,LPWSTR Name)111 BOOL AddDeviceToList(PDEVICE_LIST* pList, DWORD DeviceType, DWORD CardIndex,
112 LPWSTR Name)
113 {
114 PDEVICE_LIST pNewDevice;
115
116 DPRINT("AddDeviceToList()\n");
117
118 pNewDevice = (PDEVICE_LIST) HeapAlloc(Heap, 0,
119 sizeof(DEVICE_LIST) + lstrlen(Name) * sizeof(WCHAR));
120
121 if ( !pNewDevice )
122 {
123 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
124 return FALSE;
125 }
126
127 pNewDevice->DeviceType = DeviceType;
128 pNewDevice->CardIndex = CardIndex;
129 lstrcpy(pNewDevice->Name, Name);
130 pNewDevice->DeviceInstanceData = NULL;
131 pNewDevice->Next = *pList;
132 *pList = pNewDevice;
133
134 DPRINT("Success!\n");
135
136 return TRUE;
137 }
138
139
FreeDeviceList()140 VOID FreeDeviceList()
141 {
142 PDEVICE_LIST pDevice;
143
144 DPRINT("FreeDeviceList()\n");
145
146 while (DeviceList)
147 {
148 pDevice = DeviceList;
149 DeviceList = pDevice->Next;
150
151 if (pDevice->DeviceInstanceData)
152 HeapFree(Heap, 0, (LPVOID)pDevice->DeviceInstanceData);
153
154 HeapFree(Heap, 0, (LPSTR)pDevice);
155 }
156 }
157
158
FindDevices()159 MMRESULT FindDevices()
160 {
161 // DWORD Index;
162 // HKEY DriverKey;
163
164 DPRINT("Finding devices\n");
165
166 // DriverKey = OpenParametersKey();
167 // see drvutil.c of MS DDK for how this SHOULD be done...
168
169
170 SHORT i;
171 HANDLE h;
172 WCHAR DeviceName[SOUND_MAX_DEVICE_NAME];
173
174 for (i=0; OpenDevice(WaveOutDevice, i, &h, GENERIC_READ) == MMSYSERR_NOERROR; i++)
175 {
176 wsprintf(DeviceName, L"WaveOut%d\0", i);
177 CloseHandle(h);
178 AddDeviceToList(&DeviceList, WaveOutDevice, 0, DeviceName);
179 }
180
181 for (i=0; OpenDevice(WaveInDevice, i, &h, GENERIC_READ) == MMSYSERR_NOERROR; i++)
182 {
183 wsprintf(DeviceName, L"WaveIn%d\0", i);
184 CloseHandle(h);
185 AddDeviceToList(&DeviceList, WaveInDevice, 0, DeviceName);
186 }
187
188 for (i=0; OpenDevice(MidiOutDevice, i, &h, GENERIC_READ) == MMSYSERR_NOERROR; i++)
189 {
190 wsprintf(DeviceName, L"MidiOut%d\0", i);
191 CloseHandle(h);
192 AddDeviceToList(&DeviceList, MidiOutDevice, 0, DeviceName);
193 }
194
195 for (i=0; OpenDevice(MidiInDevice, i, &h, GENERIC_READ) == MMSYSERR_NOERROR; i++)
196 {
197 wsprintf(DeviceName, L"MidiIn%d\0", i);
198 CloseHandle(h);
199 AddDeviceToList(&DeviceList, MidiInDevice, 0, DeviceName);
200 }
201
202 for (i=0; OpenDevice(AuxDevice, i, &h, GENERIC_READ) == MMSYSERR_NOERROR; i++)
203 {
204 wsprintf(DeviceName, L"Aux%d\0", i);
205 CloseHandle(h);
206 AddDeviceToList(&DeviceList, AuxDevice, 0, DeviceName);
207 }
208
209
210 // MIDI Out 0: MPU-401 UART
211 // AddDeviceToList(&DeviceList, MidiOutDevice, 0, L"MidiOut0");
212 // Wave Out 0: Sound Blaster 16 (ok?)
213 // AddDeviceToList(&DeviceList, WaveOutDevice, 0, L"WaveOut0");
214
215 return MMSYSERR_NOERROR; // ok?
216 }
217
218
219
GetDeviceCount(UINT DeviceType)220 DWORD GetDeviceCount(UINT DeviceType)
221 {
222 int i;
223 PDEVICE_LIST List;
224
225 for (List = DeviceList, i = 0; List != NULL; List = List->Next)
226 if (List->DeviceType == DeviceType)
227 i ++;
228
229 return i;
230 }
231