Better function parameter checking.
[wine] / dlls / msacm / msacm32_main.c
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
2
3 /*
4  *      MSACM32 library
5  *
6  *      Copyright 1998  Patrik Stridvall
7  *                1999  Eric Pouech
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include <stdarg.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "wine/debug.h"
30 #include "mmsystem.h"
31 #include "mmreg.h"
32 #include "msacm.h"
33 #include "msacmdrv.h"
34 #include "wineacm.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(msacm);
37
38 /**********************************************************************/
39
40 HINSTANCE       MSACM_hInstance32 = 0;
41
42 /***********************************************************************
43  *           DllMain (MSACM32.init)
44  */
45 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
46 {
47     TRACE("%p 0x%lx %p\n", hInstDLL, fdwReason, lpvReserved);
48
49     switch (fdwReason) {
50     case DLL_PROCESS_ATTACH:
51         DisableThreadLibraryCalls(hInstDLL);
52         MSACM_hHeap = HeapCreate(0, 0x10000, 0);
53         MSACM_hInstance32 = hInstDLL;
54         MSACM_RegisterAllDrivers();
55         break;
56     case DLL_PROCESS_DETACH:
57         MSACM_UnregisterAllDrivers();
58         HeapDestroy(MSACM_hHeap);
59         MSACM_hHeap = NULL;
60         MSACM_hInstance32 = NULL;
61         break;
62     default:
63         break;
64     }
65     return TRUE;
66 }
67
68 /***********************************************************************
69  *           XRegThunkEntry (MSACM32.1)
70  * FIXME
71  *   No documentation found.
72  */
73
74 /***********************************************************************
75  *           acmGetVersion (MSACM32.@)
76  */
77 DWORD WINAPI acmGetVersion(void)
78 {
79     OSVERSIONINFOA version;
80
81     version.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
82     if (!GetVersionExA( &version ))
83         return 0x04030000;
84
85     switch (version.dwPlatformId) {
86     case VER_PLATFORM_WIN32_NT:
87         return 0x04000565; /* 4.0.1381 */
88     default:
89         FIXME("%lx not supported\n", version.dwPlatformId);
90     case VER_PLATFORM_WIN32_WINDOWS:
91         return 0x04030000; /* 4.3.0 */
92     }
93 }
94
95 /***********************************************************************
96  *           acmMessage32 (MSACM32.35)
97  * FIXME
98  *   No documentation found.
99  */
100
101 /***********************************************************************
102  *           acmMetrics (MSACM32.@)
103  */
104 MMRESULT WINAPI acmMetrics(HACMOBJ hao, UINT uMetric, LPVOID pMetric)
105 {
106     PWINE_ACMOBJ        pao = MSACM_GetObj(hao, WINE_ACMOBJ_DONTCARE);
107     BOOL                bLocal = TRUE;
108     PWINE_ACMDRIVERID   padid;
109     DWORD               val = 0;
110     int                 i;
111     MMRESULT            mmr = MMSYSERR_NOERROR;
112
113     TRACE("(%p, %d, %p);\n", hao, uMetric, pMetric);
114
115 #define CheckLocal(padid) (!bLocal || ((padid)->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_LOCAL))
116
117     switch (uMetric) {
118     case ACM_METRIC_COUNT_DRIVERS:
119         bLocal = FALSE;
120         /* fall through */
121     case ACM_METRIC_COUNT_LOCAL_DRIVERS:
122         if (hao) return MMSYSERR_INVALHANDLE;
123         if (!pMetric) return MMSYSERR_INVALPARAM;
124         for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID)
125             if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && CheckLocal(padid))
126                 val++;
127         *(LPDWORD)pMetric = val;
128         break;
129
130     case ACM_METRIC_COUNT_CODECS:
131         bLocal = FALSE;
132         /* fall through */
133     case ACM_METRIC_COUNT_LOCAL_CODECS:
134         if (hao) return MMSYSERR_INVALHANDLE;
135         if (!pMetric) return MMSYSERR_INVALPARAM;
136         for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID)
137             if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
138                 (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC) &&
139                 CheckLocal(padid))
140                 val++;
141         *(LPDWORD)pMetric = val;
142         break;
143
144     case ACM_METRIC_COUNT_CONVERTERS:
145         bLocal = FALSE;
146         /* fall through */
147     case ACM_METRIC_COUNT_LOCAL_CONVERTERS:
148         if (hao) return MMSYSERR_INVALHANDLE;
149         if (!pMetric) return MMSYSERR_INVALPARAM;
150         for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID)
151             if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
152                  (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CONVERTER) &&
153                 CheckLocal(padid))
154                 val++;
155         *(LPDWORD)pMetric = val;
156         break;
157
158     case ACM_METRIC_COUNT_FILTERS:
159         bLocal = FALSE;
160         /* fall through */
161     case ACM_METRIC_COUNT_LOCAL_FILTERS:
162         if (hao) return MMSYSERR_INVALHANDLE;
163         if (!pMetric) return MMSYSERR_INVALPARAM;
164         for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID)
165             if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
166                 (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_FILTER) &&
167                 CheckLocal(padid))
168                 val++;
169         *(LPDWORD)pMetric = val;
170         break;
171
172     case ACM_METRIC_COUNT_DISABLED:
173         bLocal = FALSE;
174         /* fall through */
175     case ACM_METRIC_COUNT_LOCAL_DISABLED:
176         if (hao) return MMSYSERR_INVALHANDLE;
177         if (!pMetric) return MMSYSERR_INVALPARAM;
178         for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID)
179             if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && CheckLocal(padid))
180                 val++;
181         *(LPDWORD)pMetric = val;
182         break;
183
184     case ACM_METRIC_MAX_SIZE_FORMAT:
185         if (hao == NULL) {
186             for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
187                 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED)) {
188                     for (i = 0; i < padid->cFormatTags; i++) {
189                         if (val < padid->aFormatTag[i].cbwfx)
190                             val = padid->aFormatTag[i].cbwfx;
191                     }
192                 }
193             }
194         } else if (pao != NULL) {
195             switch (pao->dwType) {
196             case WINE_ACMOBJ_DRIVER:
197             case WINE_ACMOBJ_DRIVERID:
198                 padid = pao->pACMDriverID;
199                 break;
200             default:
201                 return MMSYSERR_INVALHANDLE;
202             }
203             if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED)) {
204                 for (i = 0; i < padid->cFormatTags; i++) {
205                     if (val < padid->aFormatTag[i].cbwfx)
206                         val = padid->aFormatTag[i].cbwfx;
207                 }
208             }
209         } else {
210             return MMSYSERR_INVALHANDLE;
211         }
212         if (!pMetric) return MMSYSERR_INVALPARAM;
213         *(LPDWORD)pMetric = val;
214         break;
215
216     case ACM_METRIC_COUNT_HARDWARE:
217         if (hao) return MMSYSERR_INVALHANDLE;
218         if (!pMetric) return MMSYSERR_INVALPARAM;
219         *(LPDWORD)pMetric = 0;
220         FIXME("ACM_METRIC_COUNT_HARDWARE not implemented\n");
221         break;
222
223     case ACM_METRIC_HARDWARE_WAVE_INPUT:
224     case ACM_METRIC_HARDWARE_WAVE_OUTPUT:
225     case ACM_METRIC_MAX_SIZE_FILTER:
226     case ACM_METRIC_DRIVER_SUPPORT:
227     case ACM_METRIC_DRIVER_PRIORITY:
228     default:
229         FIXME("(%p, %d, %p): stub\n", hao, uMetric, pMetric);
230         mmr = MMSYSERR_NOTSUPPORTED;
231     }
232     return mmr;
233 }