1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */ 2 3 /* 4 * MSACM32 library 5 * 6 * Copyright 1998 Patrik Stridvall 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 21 */ 22 23 #include "wineacm.h" 24 25 /*********************************************************************** 26 * acmFilterChooseA (MSACM32.@) 27 */ 28 MMRESULT WINAPI acmFilterChooseA(PACMFILTERCHOOSEA pafltrc) 29 { 30 FIXME("(%p): stub\n", pafltrc); 31 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 32 return MMSYSERR_ERROR; 33 } 34 35 /*********************************************************************** 36 * acmFilterChooseW (MSACM32.@) 37 */ 38 MMRESULT WINAPI acmFilterChooseW(PACMFILTERCHOOSEW pafltrc) 39 { 40 FIXME("(%p): stub\n", pafltrc); 41 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 42 return MMSYSERR_ERROR; 43 } 44 45 /*********************************************************************** 46 * acmFilterDetailsA (MSACM32.@) 47 */ 48 MMRESULT WINAPI acmFilterDetailsA(HACMDRIVER had, PACMFILTERDETAILSA pafd, 49 DWORD fdwDetails) 50 { 51 ACMFILTERDETAILSW afdw; 52 MMRESULT mmr; 53 54 memset(&afdw, 0, sizeof(afdw)); 55 afdw.cbStruct = sizeof(afdw); 56 afdw.dwFilterIndex = pafd->dwFilterIndex; 57 afdw.dwFilterTag = pafd->dwFilterTag; 58 afdw.pwfltr = pafd->pwfltr; 59 afdw.cbwfltr = pafd->cbwfltr; 60 61 mmr = acmFilterDetailsW(had, &afdw, fdwDetails); 62 if (mmr == MMSYSERR_NOERROR) { 63 pafd->dwFilterTag = afdw.dwFilterTag; 64 pafd->fdwSupport = afdw.fdwSupport; 65 WideCharToMultiByte( CP_ACP, 0, afdw.szFilter, -1, pafd->szFilter, 66 sizeof(pafd->szFilter), NULL, NULL ); 67 } 68 return mmr; 69 } 70 71 /*********************************************************************** 72 * acmFilterDetailsW (MSACM32.@) 73 */ 74 MMRESULT WINAPI acmFilterDetailsW(HACMDRIVER had, PACMFILTERDETAILSW pafd, 75 DWORD fdwDetails) 76 { 77 MMRESULT mmr; 78 ACMFILTERTAGDETAILSA aftd; 79 80 TRACE("(%p, %p, %d)\n", had, pafd, fdwDetails); 81 82 memset(&aftd, 0, sizeof(aftd)); 83 aftd.cbStruct = sizeof(aftd); 84 85 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM; 86 87 switch (fdwDetails) { 88 case ACM_FILTERDETAILSF_FILTER: 89 if (pafd->dwFilterTag != pafd->pwfltr->dwFilterTag) { 90 mmr = MMSYSERR_INVALPARAM; 91 break; 92 } 93 if (had == NULL) { 94 PWINE_ACMDRIVERID padid; 95 96 mmr = ACMERR_NOTPOSSIBLE; 97 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { 98 /* should check for codec only */ 99 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && 100 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) { 101 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, 102 (LPARAM)pafd, (LPARAM)fdwDetails); 103 acmDriverClose(had, 0); 104 if (mmr == MMSYSERR_NOERROR) break; 105 } 106 } 107 } else { 108 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails); 109 } 110 break; 111 case ACM_FILTERDETAILSF_INDEX: 112 /* should check pafd->dwFilterIndex < aftd->cStandardFilters */ 113 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails); 114 break; 115 default: 116 WARN("Unknown fdwDetails %08x\n", fdwDetails); 117 mmr = MMSYSERR_INVALFLAG; 118 break; 119 } 120 121 TRACE("=> %d\n", mmr); 122 return mmr; 123 } 124 125 struct MSACM_FilterEnumWtoA_Instance { 126 PACMFILTERDETAILSA pafda; 127 DWORD_PTR dwInstance; 128 ACMFILTERENUMCBA fnCallback; 129 }; 130 131 static BOOL CALLBACK MSACM_FilterEnumCallbackWtoA(HACMDRIVERID hadid, 132 PACMFILTERDETAILSW pafdw, 133 DWORD_PTR dwInstance, 134 DWORD fdwSupport) 135 { 136 struct MSACM_FilterEnumWtoA_Instance* pafei; 137 138 pafei = (struct MSACM_FilterEnumWtoA_Instance*)dwInstance; 139 140 pafei->pafda->dwFilterIndex = pafdw->dwFilterIndex; 141 pafei->pafda->dwFilterTag = pafdw->dwFilterTag; 142 pafei->pafda->fdwSupport = pafdw->fdwSupport; 143 WideCharToMultiByte( CP_ACP, 0, pafdw->szFilter, -1, pafei->pafda->szFilter, 144 sizeof(pafei->pafda->szFilter), NULL, NULL ); 145 146 return (pafei->fnCallback)(hadid, pafei->pafda, 147 pafei->dwInstance, fdwSupport); 148 } 149 150 /*********************************************************************** 151 * acmFilterEnumA (MSACM32.@) 152 */ 153 MMRESULT WINAPI acmFilterEnumA(HACMDRIVER had, PACMFILTERDETAILSA pafda, 154 ACMFILTERENUMCBA fnCallback, 155 DWORD_PTR dwInstance, DWORD fdwEnum) 156 { 157 ACMFILTERDETAILSW afdw; 158 struct MSACM_FilterEnumWtoA_Instance afei; 159 160 memset(&afdw, 0, sizeof(afdw)); 161 afdw.cbStruct = sizeof(afdw); 162 afdw.dwFilterIndex = pafda->dwFilterIndex; 163 afdw.dwFilterTag = pafda->dwFilterTag; 164 afdw.pwfltr = pafda->pwfltr; 165 afdw.cbwfltr = pafda->cbwfltr; 166 167 afei.pafda = pafda; 168 afei.dwInstance = dwInstance; 169 afei.fnCallback = fnCallback; 170 171 return acmFilterEnumW(had, &afdw, MSACM_FilterEnumCallbackWtoA, 172 (DWORD_PTR)&afei, fdwEnum); 173 } 174 175 static BOOL MSACM_FilterEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had, 176 PACMFILTERDETAILSW pafd, 177 ACMFILTERENUMCBW fnCallback, 178 DWORD_PTR dwInstance, DWORD fdwEnum) 179 { 180 ACMFILTERTAGDETAILSW aftd; 181 unsigned int i, j; 182 183 for (i = 0; i < padid->cFilterTags; i++) { 184 memset(&aftd, 0, sizeof(aftd)); 185 aftd.cbStruct = sizeof(aftd); 186 aftd.dwFilterTagIndex = i; 187 if (acmFilterTagDetailsW(had, &aftd, ACM_FILTERTAGDETAILSF_INDEX) != MMSYSERR_NOERROR) 188 continue; 189 190 if ((fdwEnum & ACM_FILTERENUMF_DWFILTERTAG) && 191 aftd.dwFilterTag != pafd->pwfltr->dwFilterTag) 192 continue; 193 194 for (j = 0; j < aftd.cStandardFilters; j++) { 195 pafd->dwFilterIndex = j; 196 pafd->dwFilterTag = aftd.dwFilterTag; 197 if (acmFilterDetailsW(had, pafd, ACM_FILTERDETAILSF_INDEX) != MMSYSERR_NOERROR) 198 continue; 199 200 if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, padid->fdwSupport)) 201 return FALSE; 202 } 203 } 204 return TRUE; 205 } 206 207 /*********************************************************************** 208 * acmFilterEnumW (MSACM32.@) 209 */ 210 MMRESULT WINAPI acmFilterEnumW(HACMDRIVER had, PACMFILTERDETAILSW pafd, 211 ACMFILTERENUMCBW fnCallback, 212 DWORD_PTR dwInstance, DWORD fdwEnum) 213 { 214 PWINE_ACMDRIVERID padid; 215 BOOL ret; 216 217 TRACE("(%p, %p, %p, %ld, %d)\n", 218 had, pafd, fnCallback, dwInstance, fdwEnum); 219 220 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM; 221 222 if (fdwEnum & ~(ACM_FILTERENUMF_DWFILTERTAG)) 223 FIXME("Unsupported fdwEnum values\n"); 224 225 if (had) { 226 HACMDRIVERID hadid; 227 228 if (acmDriverID((HACMOBJ)had, &hadid, 0) != MMSYSERR_NOERROR) 229 return MMSYSERR_INVALHANDLE; 230 MSACM_FilterEnumHelper(MSACM_GetDriverID(hadid), had, pafd, 231 fnCallback, dwInstance, fdwEnum); 232 return MMSYSERR_NOERROR; 233 } 234 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { 235 /* should check for codec only */ 236 if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) || 237 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR) 238 continue; 239 ret = MSACM_FilterEnumHelper(padid, had, pafd, 240 fnCallback, dwInstance, fdwEnum); 241 acmDriverClose(had, 0); 242 if (!ret) break; 243 } 244 return MMSYSERR_NOERROR; 245 } 246 247 /*********************************************************************** 248 * acmFilterTagDetailsA (MSACM32.@) 249 */ 250 MMRESULT WINAPI acmFilterTagDetailsA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda, 251 DWORD fdwDetails) 252 { 253 ACMFILTERTAGDETAILSW aftdw; 254 MMRESULT mmr; 255 256 memset(&aftdw, 0, sizeof(aftdw)); 257 aftdw.cbStruct = sizeof(aftdw); 258 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex; 259 aftdw.dwFilterTag = paftda->dwFilterTag; 260 261 mmr = acmFilterTagDetailsW(had, &aftdw, fdwDetails); 262 if (mmr == MMSYSERR_NOERROR) { 263 paftda->dwFilterTag = aftdw.dwFilterTag; 264 paftda->dwFilterTagIndex = aftdw.dwFilterTagIndex; 265 paftda->cbFilterSize = aftdw.cbFilterSize; 266 paftda->fdwSupport = aftdw.fdwSupport; 267 paftda->cStandardFilters = aftdw.cStandardFilters; 268 WideCharToMultiByte( CP_ACP, 0, aftdw.szFilterTag, -1, paftda->szFilterTag, 269 sizeof(paftda->szFilterTag), NULL, NULL ); 270 } 271 return mmr; 272 } 273 274 /*********************************************************************** 275 * acmFilterTagDetailsW (MSACM32.@) 276 */ 277 MMRESULT WINAPI acmFilterTagDetailsW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd, 278 DWORD fdwDetails) 279 { 280 PWINE_ACMDRIVERID padid; 281 MMRESULT mmr; 282 283 TRACE("(%p, %p, %d)\n", had, paftd, fdwDetails); 284 285 if (fdwDetails & ~(ACM_FILTERTAGDETAILSF_FILTERTAG|ACM_FILTERTAGDETAILSF_INDEX| 286 ACM_FILTERTAGDETAILSF_LARGESTSIZE)) 287 return MMSYSERR_INVALFLAG; 288 289 switch (fdwDetails) { 290 case ACM_FILTERTAGDETAILSF_FILTERTAG: 291 if (had == NULL) { 292 mmr = ACMERR_NOTPOSSIBLE; 293 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { 294 /* should check for codec only */ 295 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && 296 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) { 297 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails); 298 acmDriverClose(had, 0); 299 if (mmr == MMSYSERR_NOERROR) break; 300 } 301 } 302 } else { 303 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails); 304 } 305 break; 306 307 case ACM_FILTERTAGDETAILSF_INDEX: 308 /* FIXME should check paftd->dwFilterTagIndex < add.cFilterTags */ 309 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails); 310 break; 311 312 case ACM_FILTERTAGDETAILSF_LARGESTSIZE: 313 if (had == NULL) { 314 ACMFILTERTAGDETAILSW tmp; 315 DWORD ft = paftd->dwFilterTag; 316 317 mmr = ACMERR_NOTPOSSIBLE; 318 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { 319 /* should check for codec only */ 320 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && 321 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) { 322 323 memset(&tmp, 0, sizeof(tmp)); 324 tmp.cbStruct = sizeof(tmp); 325 tmp.dwFilterTag = ft; 326 327 if (MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, 328 (LPARAM)&tmp, fdwDetails) == MMSYSERR_NOERROR) { 329 if (mmr == ACMERR_NOTPOSSIBLE || 330 paftd->cbFilterSize < tmp.cbFilterSize) { 331 *paftd = tmp; 332 mmr = MMSYSERR_NOERROR; 333 } 334 } 335 acmDriverClose(had, 0); 336 } 337 } 338 } else { 339 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails); 340 } 341 break; 342 343 default: 344 WARN("Unsupported fdwDetails=%08x\n", fdwDetails); 345 mmr = MMSYSERR_ERROR; 346 } 347 348 if (mmr == MMSYSERR_NOERROR && 349 paftd->dwFilterTag == WAVE_FORMAT_PCM && paftd->szFilterTag[0] == 0) 350 MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFilterTag, 351 sizeof(paftd->szFilterTag)/sizeof(WCHAR) ); 352 353 return mmr; 354 } 355 356 struct MSACM_FilterTagEnumWtoA_Instance { 357 PACMFILTERTAGDETAILSA paftda; 358 DWORD_PTR dwInstance; 359 ACMFILTERTAGENUMCBA fnCallback; 360 }; 361 362 static BOOL CALLBACK MSACM_FilterTagEnumCallbackWtoA(HACMDRIVERID hadid, 363 PACMFILTERTAGDETAILSW paftdw, 364 DWORD_PTR dwInstance, 365 DWORD fdwSupport) 366 { 367 struct MSACM_FilterTagEnumWtoA_Instance* paftei; 368 369 paftei = (struct MSACM_FilterTagEnumWtoA_Instance*)dwInstance; 370 371 paftei->paftda->dwFilterTagIndex = paftdw->dwFilterTagIndex; 372 paftei->paftda->dwFilterTag = paftdw->dwFilterTag; 373 paftei->paftda->cbFilterSize = paftdw->cbFilterSize; 374 paftei->paftda->fdwSupport = paftdw->fdwSupport; 375 paftei->paftda->cStandardFilters = paftdw->cStandardFilters; 376 WideCharToMultiByte( CP_ACP, 0, paftdw->szFilterTag, -1, paftei->paftda->szFilterTag, 377 sizeof(paftei->paftda->szFilterTag), NULL, NULL ); 378 379 return (paftei->fnCallback)(hadid, paftei->paftda, 380 paftei->dwInstance, fdwSupport); 381 } 382 383 /*********************************************************************** 384 * acmFilterTagEnumA (MSACM32.@) 385 */ 386 MMRESULT WINAPI acmFilterTagEnumA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda, 387 ACMFILTERTAGENUMCBA fnCallback, 388 DWORD_PTR dwInstance, DWORD fdwEnum) 389 { 390 ACMFILTERTAGDETAILSW aftdw; 391 struct MSACM_FilterTagEnumWtoA_Instance aftei; 392 393 memset(&aftdw, 0, sizeof(aftdw)); 394 aftdw.cbStruct = sizeof(aftdw); 395 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex; 396 aftdw.dwFilterTag = paftda->dwFilterTag; 397 398 aftei.paftda = paftda; 399 aftei.dwInstance = dwInstance; 400 aftei.fnCallback = fnCallback; 401 402 return acmFilterTagEnumW(had, &aftdw, MSACM_FilterTagEnumCallbackWtoA, 403 (DWORD_PTR)&aftei, fdwEnum); 404 } 405 406 /*********************************************************************** 407 * acmFilterTagEnumW (MSACM32.@) 408 */ 409 MMRESULT WINAPI acmFilterTagEnumW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd, 410 ACMFILTERTAGENUMCBW fnCallback, 411 DWORD_PTR dwInstance, DWORD fdwEnum) 412 { 413 PWINE_ACMDRIVERID padid; 414 unsigned int i; 415 416 TRACE("(%p, %p, %p, %ld, %d)\n", 417 had, paftd, fnCallback, dwInstance, fdwEnum); 418 419 if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM; 420 421 if (had) FIXME("had != NULL, not supported\n"); 422 423 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { 424 /* should check for codec only */ 425 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && 426 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) { 427 428 for (i = 0; i < padid->cFilterTags; i++) { 429 paftd->dwFilterTagIndex = i; 430 if (acmFilterTagDetailsW(had, paftd, ACM_FILTERTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) { 431 if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) { 432 padid = NULL; 433 break; 434 } 435 } 436 } 437 acmDriverClose(had, 0); 438 } 439 } 440 return MMSYSERR_NOERROR; 441 } 442