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