1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Configuration of network devices 4 * FILE: dll/directx/dsound_new/enum.c 5 * PURPOSE: Handles DSound device enumeration 6 * 7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org) 8 */ 9 10 #include "precomp.h" 11 12 VOID 13 LoadResourceString( 14 UINT ResourceId, 15 LPVOID Buffer, 16 UINT ccount, 17 LPVOID DefaultString, 18 BOOL bUnicode) 19 { 20 if (bUnicode) 21 { 22 /* load localized string */ 23 if (!LoadStringW(dsound_hInstance, ResourceId, (LPWSTR)Buffer, ccount)) 24 { 25 /* default device name */ 26 wcscpy((LPWSTR)Buffer, (LPWSTR)DefaultString); 27 } 28 } 29 else 30 { 31 /* load localized string */ 32 if (!LoadStringA(dsound_hInstance, ResourceId, (LPSTR)Buffer, ccount)) 33 { 34 /* default device name */ 35 strcpy((LPSTR)Buffer, (LPSTR)DefaultString); 36 } 37 } 38 } 39 40 41 BOOL 42 DoDSoundCallback( 43 LPDSENUMCALLBACKA lpDSEnumCallbackA, 44 LPDSENUMCALLBACKW lpDSEnumCallbackW, 45 LPGUID DeviceGuid, 46 UINT ResourceId, 47 LPWSTR ProductName, 48 LPWSTR DriverName, 49 LPVOID lpContext) 50 { 51 WCHAR Buffer[200] = {0}; 52 char DriverNameA[200]; 53 54 static LPWSTR SoundDriverW = L"Primary Sound Driver"; 55 static LPWSTR SoundDriverA = L"Primary Sound Driver"; 56 57 if (lpDSEnumCallbackW) 58 { 59 if (ResourceId) 60 { 61 /* load resource string */ 62 Buffer[0] = 0; 63 LoadResourceString(ResourceId, (LPVOID)Buffer, sizeof(Buffer)/sizeof(WCHAR), (LPVOID)SoundDriverW, TRUE); 64 Buffer[(sizeof(Buffer)/sizeof(WCHAR))-1] = '\0'; 65 } 66 else 67 { 68 /* use passed string */ 69 ASSERT(ProductName); 70 wcscpy(Buffer, ProductName); 71 } 72 73 /* perform callback */ 74 return lpDSEnumCallbackW(DeviceGuid, Buffer, DriverName, lpContext); 75 } 76 else 77 { 78 if (ResourceId) 79 { 80 /* load resource string */ 81 Buffer[0] = 0; 82 LoadResourceString(ResourceId, (LPVOID)Buffer, sizeof(Buffer)/sizeof(char), (LPVOID)SoundDriverA, FALSE); 83 Buffer[(sizeof(Buffer)/sizeof(WCHAR))-1] = 0; 84 } 85 else 86 { 87 /* use passed string */ 88 Buffer[0] = 0; 89 WideCharToMultiByte(CP_ACP, 0, ProductName, -1, (LPSTR)Buffer, sizeof(Buffer) / sizeof(char), NULL, NULL); 90 Buffer[(sizeof(Buffer)/sizeof(WCHAR))-1] = 0; 91 } 92 93 DriverNameA[0] = 0; 94 if (ProductName) 95 { 96 WideCharToMultiByte(CP_ACP, 0, ProductName, -1, DriverNameA, sizeof(DriverNameA) / sizeof(char), NULL, NULL); 97 DriverNameA[(sizeof(DriverNameA) / sizeof(char))-1] = 0; 98 } 99 100 return lpDSEnumCallbackA(DeviceGuid, (LPSTR)Buffer, DriverNameA, lpContext); 101 } 102 } 103 104 105 HRESULT 106 DSoundEnumerate( 107 LPDSENUMCALLBACKA lpDSEnumCallbackA, 108 LPDSENUMCALLBACKW lpDSEnumCallbackW, 109 LPVOID lpContext, 110 BOOL bPlayback) 111 { 112 ULONG ResourceId; 113 BOOL bResult; 114 LPFILTERINFO CurInfo; 115 WAVEOUTCAPSW WaveOutCaps; 116 WAVEINCAPSW WaveInCaps; 117 118 if (!RootInfo) 119 { 120 EnumAudioDeviceInterfaces(&RootInfo); 121 } 122 123 if (lpDSEnumCallbackA == NULL && lpDSEnumCallbackW == NULL) 124 { 125 DPRINT("No callback\n"); 126 return DSERR_INVALIDPARAM; 127 } 128 129 if (bPlayback) 130 { 131 /* use resource id of playback string */ 132 ResourceId = IDS_PRIMARY_PLAYBACK_DEVICE; 133 } 134 else 135 { 136 /* use resource id of playback string */ 137 ResourceId = IDS_PRIMARY_RECORD_DEVICE; 138 } 139 140 if (RootInfo) 141 { 142 /* perform first callback */ 143 bResult = DoDSoundCallback(lpDSEnumCallbackA, lpDSEnumCallbackW, NULL, ResourceId, NULL, L"", lpContext); 144 if (!bResult) 145 { 146 /* callback asked as to stop */ 147 return DS_OK; 148 } 149 150 /* now iterate through all devices */ 151 CurInfo = RootInfo; 152 153 do 154 { 155 if (bPlayback && !IsEqualGUID(&CurInfo->DeviceGuid[1], &GUID_NULL)) 156 { 157 RtlZeroMemory(&WaveOutCaps, sizeof(WAVEOUTCAPSW)); 158 159 /* sanity check */ 160 ASSERT(CurInfo->MappedId[1] != ULONG_MAX); 161 162 /* get wave out caps */ 163 waveOutGetDevCapsW((UINT_PTR)CurInfo->MappedId[1], &WaveOutCaps, sizeof(WAVEOUTCAPSW)); 164 WaveOutCaps.szPname[MAXPNAMELEN-1] = L'\0'; 165 166 bResult = DoDSoundCallback(lpDSEnumCallbackA, lpDSEnumCallbackW, &CurInfo->DeviceGuid[1], 0, WaveOutCaps.szPname, L"" /* FIXME */, lpContext); 167 if (!bResult) 168 { 169 /* callback asked as to stop */ 170 return DS_OK; 171 } 172 } 173 else if (!bPlayback && !IsEqualGUID(&CurInfo->DeviceGuid[0], &GUID_NULL)) 174 { 175 RtlZeroMemory(&WaveInCaps, sizeof(WAVEINCAPSW)); 176 177 /* sanity check */ 178 ASSERT(CurInfo->MappedId[1] != ULONG_MAX); 179 180 /* get wave in caps */ 181 waveInGetDevCapsW((UINT_PTR)CurInfo->MappedId[0], &WaveInCaps, sizeof(WAVEINCAPSW)); 182 WaveInCaps.szPname[MAXPNAMELEN-1] = L'\0'; 183 184 bResult = DoDSoundCallback(lpDSEnumCallbackA, lpDSEnumCallbackW, &CurInfo->DeviceGuid[0], 0, WaveInCaps.szPname, L"" /* FIXME */, lpContext); 185 if (!bResult) 186 { 187 /* callback asked as to stop */ 188 return DS_OK; 189 } 190 } 191 192 /* move to next entry */ 193 CurInfo = CurInfo->lpNext; 194 }while(CurInfo); 195 } 196 return DS_OK; 197 } 198 199 HRESULT 200 WINAPI 201 DirectSoundEnumerateA( 202 LPDSENUMCALLBACKA lpDSEnumCallback, 203 LPVOID lpContext) 204 { 205 return DSoundEnumerate(lpDSEnumCallback, NULL, lpContext, TRUE); 206 } 207 208 HRESULT 209 WINAPI 210 DirectSoundEnumerateW( 211 LPDSENUMCALLBACKW lpDSEnumCallback, 212 LPVOID lpContext ) 213 { 214 return DSoundEnumerate(NULL, lpDSEnumCallback, lpContext, TRUE); 215 } 216 217 HRESULT 218 WINAPI 219 DirectSoundCaptureEnumerateA( 220 LPDSENUMCALLBACKA lpDSEnumCallback, 221 LPVOID lpContext) 222 { 223 return DSoundEnumerate(lpDSEnumCallback, NULL, lpContext, FALSE); 224 } 225 226 HRESULT 227 WINAPI 228 DirectSoundCaptureEnumerateW( 229 LPDSENUMCALLBACKW lpDSEnumCallback, 230 LPVOID lpContext) 231 { 232 return DSoundEnumerate(NULL, lpDSEnumCallback, lpContext, FALSE); 233 } 234