| /* | |
| * Unit tests for msacm functions | |
| * | |
| * Copyright (c) 2004 Robert Reif | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * This library is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; if not, write to the Free Software | |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| */ | |
| #include <stdarg.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <math.h> | |
| #include "wine/test.h" | |
| #include "windef.h" | |
| #include "winbase.h" | |
| #include "winnls.h" | |
| #include "mmsystem.h" | |
| #define NOBITMAP | |
| #include "mmreg.h" | |
| #include "msacm.h" | |
| static BOOL CALLBACK FormatTagEnumProc(HACMDRIVERID hadid, | |
| PACMFORMATTAGDETAILS paftd, | |
| DWORD dwInstance, | |
| DWORD fdwSupport) | |
| { | |
| if (winetest_interactive) | |
| trace(" Format 0x%04lx: %s\n", paftd->dwFormatTag, paftd->szFormatTag); | |
| return TRUE; | |
| } | |
| static BOOL CALLBACK FormatEnumProc(HACMDRIVERID hadid, | |
| LPACMFORMATDETAILS pafd, | |
| DWORD dwInstance, | |
| DWORD fd) | |
| { | |
| if (winetest_interactive) | |
| trace(" 0x%04lx, %s\n", pafd->dwFormatTag, pafd->szFormat); | |
| return TRUE; | |
| } | |
| static BOOL CALLBACK DriverEnumProc(HACMDRIVERID hadid, | |
| DWORD dwInstance, | |
| DWORD fdwSupport) | |
| { | |
| MMRESULT rc; | |
| ACMDRIVERDETAILS dd; | |
| HACMDRIVER had; | |
| if (winetest_interactive) { | |
| trace("id: %p\n", hadid); | |
| trace(" Supports:\n"); | |
| if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_ASYNC) | |
| trace(" async conversions\n"); | |
| if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC) | |
| trace(" different format conversions\n"); | |
| if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CONVERTER) | |
| trace(" same format conversions\n"); | |
| if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_FILTER) | |
| trace(" filtering\n"); | |
| } | |
| /* try an invalid pointer */ | |
| rc = acmDriverDetails(hadid, 0, 0); | |
| ok(rc == MMSYSERR_INVALPARAM, | |
| "acmDriverDetails(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALPARAM); | |
| /* try an invalid structure size */ | |
| ZeroMemory(&dd, sizeof(dd)); | |
| rc = acmDriverDetails(hadid, &dd, 0); | |
| ok(rc == MMSYSERR_INVALPARAM, | |
| "acmDriverDetails(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALPARAM); | |
| /* MSDN says this should fail but it doesn't in practice */ | |
| dd.cbStruct = 4; | |
| rc = acmDriverDetails(hadid, &dd, 0); | |
| ok(rc == MMSYSERR_NOERROR, | |
| "acmDriverDetails(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_NOERROR); | |
| /* try an invalid handle */ | |
| dd.cbStruct = sizeof(dd); | |
| rc = acmDriverDetails((HACMDRIVERID)1, &dd, 0); | |
| ok(rc == MMSYSERR_INVALHANDLE, | |
| "acmDriverDetails(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALHANDLE); | |
| /* try an invalid handle and pointer */ | |
| rc = acmDriverDetails((HACMDRIVERID)1, 0, 0); | |
| ok(rc == MMSYSERR_INVALPARAM, | |
| "acmDriverDetails(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALPARAM); | |
| /* try invalid details */ | |
| rc = acmDriverDetails(hadid, &dd, -1); | |
| ok(rc == MMSYSERR_INVALFLAG, | |
| "acmDriverDetails(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALFLAG); | |
| /* try valid parameters */ | |
| rc = acmDriverDetails(hadid, &dd, 0); | |
| ok(rc == MMSYSERR_NOERROR, | |
| "acmDriverDetails(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_NOERROR); | |
| if (rc == MMSYSERR_NOERROR && winetest_interactive) { | |
| trace(" Short name: %s\n", dd.szShortName); | |
| trace(" Long name: %s\n", dd.szLongName); | |
| trace(" Copyright: %s\n", dd.szCopyright); | |
| trace(" Licensing: %s\n", dd.szLicensing); | |
| trace(" Features: %s\n", dd.szFeatures); | |
| trace(" Supports %lu formats\n", dd.cFormatTags); | |
| trace(" Supports %lu filter formats\n", dd.cFilterTags); | |
| } | |
| /* try invalid pointer */ | |
| rc = acmDriverOpen(0, hadid, 0); | |
| ok(rc == MMSYSERR_INVALPARAM, | |
| "acmDriverOpen(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALPARAM); | |
| /* try invalid handle */ | |
| rc = acmDriverOpen(&had, (HACMDRIVERID)1, 0); | |
| ok(rc == MMSYSERR_INVALHANDLE, | |
| "acmDriverOpen(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALHANDLE); | |
| /* try invalid open */ | |
| rc = acmDriverOpen(&had, hadid, -1); | |
| ok(rc == MMSYSERR_INVALFLAG, | |
| "acmDriverOpen(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALFLAG); | |
| /* try valid parameters */ | |
| rc = acmDriverOpen(&had, hadid, 0); | |
| ok(rc == MMSYSERR_NOERROR, | |
| "acmDriverOpen(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_NOERROR); | |
| if (rc == MMSYSERR_NOERROR) { | |
| DWORD dwSize; | |
| HACMDRIVERID hid; | |
| /* try bad pointer */ | |
| rc = acmDriverID((HACMOBJ)had, 0, 0); | |
| ok(rc == MMSYSERR_INVALPARAM, | |
| "acmDriverID(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALPARAM); | |
| /* try bad handle */ | |
| rc = acmDriverID((HACMOBJ)1, &hid, 0); | |
| ok(rc == MMSYSERR_INVALHANDLE, | |
| "acmMetrics(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALHANDLE); | |
| /* try bad handle and pointer */ | |
| rc = acmDriverID((HACMOBJ)1, 0, 0); | |
| ok(rc == MMSYSERR_INVALHANDLE, | |
| "acmMetrics(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALHANDLE); | |
| /* try bad flag */ | |
| rc = acmDriverID((HACMOBJ)had, &hid, 1); | |
| ok(rc == MMSYSERR_INVALFLAG, | |
| "acmDriverID(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALFLAG); | |
| /* try valid parameters */ | |
| rc = acmDriverID((HACMOBJ)had, &hid, 0); | |
| ok(rc == MMSYSERR_NOERROR, | |
| "acmDriverID(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_NOERROR); | |
| ok(hid == hadid, | |
| "acmDriverID() returned ID %08lx doesn't equal %08lx\n", | |
| (DWORD)hid, (DWORD)hadid); | |
| /* try bad pointer */ | |
| rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, 0); | |
| ok(rc == MMSYSERR_INVALPARAM, | |
| "acmMetrics(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALPARAM); | |
| /* try bad handle */ | |
| rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize); | |
| ok(rc == MMSYSERR_INVALHANDLE, | |
| "acmMetrics(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALHANDLE); | |
| /* try bad pointer and handle */ | |
| rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, 0); | |
| ok(rc == MMSYSERR_INVALHANDLE, | |
| "acmMetrics(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALHANDLE); | |
| /* try valid parameters */ | |
| rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize); | |
| ok(rc == MMSYSERR_NOERROR, | |
| "acmMetrics(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_NOERROR); | |
| if (rc == MMSYSERR_NOERROR) { | |
| ACMFORMATDETAILS fd; | |
| WAVEFORMATEX * pwfx; | |
| ACMFORMATTAGDETAILS aftd; | |
| /* try bad pointer */ | |
| rc = acmFormatEnum(had, 0, FormatEnumProc, 0, 0); | |
| ok(rc == MMSYSERR_INVALPARAM, | |
| "acmFormatEnum(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALPARAM); | |
| /* try bad structure size */ | |
| ZeroMemory(&fd, sizeof(fd)); | |
| rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0); | |
| ok(rc == MMSYSERR_INVALPARAM, | |
| "acmFormatEnum(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALPARAM); | |
| fd.cbStruct = sizeof(fd) - 1; | |
| rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0); | |
| ok(rc == MMSYSERR_INVALPARAM, | |
| "acmFormatEnum(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALPARAM); | |
| if (dwSize < sizeof(WAVEFORMATEX)) | |
| dwSize = sizeof(WAVEFORMATEX); | |
| pwfx = (WAVEFORMATEX *) malloc(dwSize); | |
| ZeroMemory(pwfx, dwSize); | |
| pwfx->cbSize = LOWORD(dwSize) - sizeof(WAVEFORMATEX); | |
| pwfx->wFormatTag = WAVE_FORMAT_UNKNOWN; | |
| fd.cbStruct = sizeof(fd); | |
| fd.pwfx = pwfx; | |
| fd.cbwfx = dwSize; | |
| fd.dwFormatTag = WAVE_FORMAT_UNKNOWN; | |
| /* try valid parameters */ | |
| rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0); | |
| ok(rc == MMSYSERR_NOERROR, | |
| "acmFormatEnum(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_NOERROR); | |
| /* try bad pointer */ | |
| rc = acmFormatTagEnum(had, 0, FormatTagEnumProc, 0, 0); | |
| ok(rc == MMSYSERR_INVALPARAM, | |
| "acmFormatTagEnum(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALPARAM); | |
| /* try bad structure size */ | |
| ZeroMemory(&aftd, sizeof(fd)); | |
| rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0); | |
| ok(rc == MMSYSERR_INVALPARAM, | |
| "acmFormatTagEnum(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALPARAM); | |
| aftd.cbStruct = sizeof(aftd) - 1; | |
| rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0); | |
| ok(rc == MMSYSERR_INVALPARAM, | |
| "acmFormatTagEnum(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALPARAM); | |
| aftd.cbStruct = sizeof(aftd); | |
| aftd.dwFormatTag = WAVE_FORMAT_UNKNOWN; | |
| /* try bad flag */ | |
| rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 1); | |
| ok(rc == MMSYSERR_INVALFLAG, | |
| "acmFormatTagEnum(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALFLAG); | |
| /* try valid parameters */ | |
| rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0); | |
| ok(rc == MMSYSERR_NOERROR, | |
| "acmFormatTagEnum(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_NOERROR); | |
| free(pwfx); | |
| /* try invalid handle */ | |
| rc = acmDriverClose((HACMDRIVER)1, 0); | |
| ok(rc == MMSYSERR_INVALHANDLE, | |
| "acmDriverClose(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALHANDLE); | |
| /* try invalid flag */ | |
| rc = acmDriverClose(had, 1); | |
| ok(rc == MMSYSERR_INVALFLAG, | |
| "acmDriverClose(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALFLAG); | |
| /* try valid parameters */ | |
| rc = acmDriverClose(had, 0); | |
| ok(rc == MMSYSERR_NOERROR, | |
| "acmDriverClose(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_NOERROR); | |
| /* try closing again */ | |
| rc = acmDriverClose(had, 0); | |
| ok(rc == MMSYSERR_INVALHANDLE, | |
| "acmDriverClose(): rc = %08x, should be %08x\n", | |
| rc, MMSYSERR_INVALHANDLE); | |
| } | |
| } | |
| return TRUE; | |
| } | |
| static const char * get_metric(UINT uMetric) | |
| { | |
| switch (uMetric) { | |
| case ACM_METRIC_COUNT_CODECS: | |
| return "ACM_METRIC_COUNT_CODECS"; | |
| case ACM_METRIC_COUNT_CONVERTERS: | |
| return "ACM_METRIC_COUNT_CONVERTERS"; | |
| case ACM_METRIC_COUNT_DISABLED: | |
| return "ACM_METRIC_COUNT_DISABLED"; | |
| case ACM_METRIC_COUNT_DRIVERS: | |
| return "ACM_METRIC_COUNT_DRIVERS"; | |
| case ACM_METRIC_COUNT_FILTERS: | |
| return "ACM_METRIC_COUNT_FILTERS"; | |
| case ACM_METRIC_COUNT_HARDWARE: | |
| return "ACM_METRIC_COUNT_HARDWARE"; | |
| case ACM_METRIC_COUNT_LOCAL_CODECS: | |
| return "ACM_METRIC_COUNT_LOCAL_CODECS"; | |
| case ACM_METRIC_COUNT_LOCAL_CONVERTERS: | |
| return "ACM_METRIC_COUNT_LOCAL_CONVERTERS"; | |
| case ACM_METRIC_COUNT_LOCAL_DISABLED: | |
| return "ACM_METRIC_COUNT_LOCAL_DISABLED"; | |
| case ACM_METRIC_COUNT_LOCAL_DRIVERS: | |
| return "ACM_METRIC_COUNT_LOCAL_DRIVERS"; | |
| case ACM_METRIC_COUNT_LOCAL_FILTERS: | |
| return "ACM_METRIC_COUNT_LOCAL_FILTERS"; | |
| case ACM_METRIC_DRIVER_PRIORITY: | |
| return "ACM_METRIC_DRIVER_PRIORITY"; | |
| case ACM_METRIC_DRIVER_SUPPORT: | |
| return "ACM_METRIC_DRIVER_SUPPORT"; | |
| case ACM_METRIC_HARDWARE_WAVE_INPUT: | |
| return "ACM_METRIC_HARDWARE_WAVE_INPUT"; | |
| case ACM_METRIC_HARDWARE_WAVE_OUTPUT: | |
| return "ACM_METRIC_HARDWARE_WAVE_OUTPUT"; | |
| case ACM_METRIC_MAX_SIZE_FILTER: | |
| return "ACM_METRIC_MAX_SIZE_FILTER"; | |
| case ACM_METRIC_MAX_SIZE_FORMAT: | |
| return "ACM_METRIC_MAX_SIZE_FORMAT"; | |
| } | |
| return "UNKNOWN"; | |
| } | |
| static DWORD check_count(UINT uMetric) | |
| { | |
| DWORD dwMetric; | |
| MMRESULT rc; | |
| /* try invalid result pointer */ | |
| rc = acmMetrics(NULL, uMetric, 0); | |
| ok(rc == MMSYSERR_INVALPARAM, | |
| "acmMetrics(NULL, %s, 0): rc = 0x%08x, should be 0x%08x\n", | |
| get_metric(uMetric), rc, MMSYSERR_INVALPARAM); | |
| /* try invalid handle */ | |
| rc = acmMetrics((HACMOBJ)1, uMetric, &dwMetric); | |
| ok(rc == MMSYSERR_INVALHANDLE, | |
| "acmMetrics(1, %s, %p): rc = 0x%08x, should be 0x%08x\n", | |
| get_metric(uMetric), &dwMetric, rc, MMSYSERR_INVALHANDLE); | |
| /* try invalid result pointer and handle */ | |
| rc = acmMetrics((HACMOBJ)1, uMetric, 0); | |
| ok(rc == MMSYSERR_INVALHANDLE, | |
| "acmMetrics(1, %s, 0): rc = 0x%08x, should be 0x%08x\n", | |
| get_metric(uMetric), rc, MMSYSERR_INVALHANDLE); | |
| /* try valid parameters */ | |
| rc = acmMetrics(NULL, uMetric, &dwMetric); | |
| ok(rc == MMSYSERR_NOERROR, "acmMetrics() failed: rc = 0x%08x\n", rc); | |
| if (rc == MMSYSERR_NOERROR && winetest_interactive) | |
| trace("%s: %lu\n", get_metric(uMetric), dwMetric); | |
| return dwMetric; | |
| } | |
| static void msacm_tests() | |
| { | |
| MMRESULT rc; | |
| DWORD dwCount; | |
| DWORD dwACMVersion = acmGetVersion(); | |
| if (winetest_interactive) { | |
| trace("ACM version = %u.%02u build %u%s\n", | |
| HIWORD(dwACMVersion) >> 8, | |
| HIWORD(dwACMVersion) & 0xff, | |
| LOWORD(dwACMVersion), | |
| LOWORD(dwACMVersion) == 0 ? " (Retail)" : ""); | |
| } | |
| dwCount = check_count(ACM_METRIC_COUNT_CODECS); | |
| dwCount = check_count(ACM_METRIC_COUNT_CONVERTERS); | |
| dwCount = check_count(ACM_METRIC_COUNT_DISABLED); | |
| dwCount = check_count(ACM_METRIC_COUNT_DRIVERS); | |
| dwCount = check_count(ACM_METRIC_COUNT_FILTERS); | |
| dwCount = check_count(ACM_METRIC_COUNT_HARDWARE); | |
| dwCount = check_count(ACM_METRIC_COUNT_LOCAL_CODECS); | |
| dwCount = check_count(ACM_METRIC_COUNT_LOCAL_CONVERTERS); | |
| dwCount = check_count(ACM_METRIC_COUNT_LOCAL_DISABLED); | |
| dwCount = check_count(ACM_METRIC_COUNT_LOCAL_DRIVERS); | |
| dwCount = check_count(ACM_METRIC_COUNT_LOCAL_FILTERS); | |
| if (winetest_interactive) | |
| trace("enabled drivers:\n"); | |
| rc = acmDriverEnum(DriverEnumProc, 0, 0); | |
| ok(rc == MMSYSERR_NOERROR, | |
| "acmDriverEnum() failed, rc=%08x, should be 0x%08x\n", | |
| rc, MMSYSERR_NOERROR); | |
| } | |
| START_TEST(msacm) | |
| { | |
| msacm_tests(); | |
| } |