Release 20030408.
[wine/gsoc-2012-control.git] / dlls / msacm / driver.c
blobef8b93c044b672cb9d6b25b0e48b7dea6aa26dee
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
3 /*
4 * MSACM32 library
6 * Copyright 1998 Patrik Stridvall
7 * 1999 Eric Pouech
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.
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.
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
24 #include "config.h"
25 #include "wine/port.h"
27 #include <stdio.h>
29 #include "winbase.h"
30 #include "winerror.h"
31 #include "windef.h"
32 #include "wingdi.h"
33 #include "winuser.h"
34 #include "winnls.h"
35 #include "mmsystem.h"
36 #include "msacm.h"
37 #include "msacmdrv.h"
38 #include "wineacm.h"
39 #include "winreg.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(msacm);
44 /***********************************************************************
45 * acmDriverAddA (MSACM32.@)
47 MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule,
48 LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
50 if (!phadid)
51 return MMSYSERR_INVALPARAM;
53 /* Check if any unknown flags */
54 if (fdwAdd &
55 ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND|
56 ACM_DRIVERADDF_GLOBAL))
57 return MMSYSERR_INVALFLAG;
59 /* Check if any incompatible flags */
60 if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) &&
61 (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND))
62 return MMSYSERR_INVALFLAG;
64 /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a
65 * LoadDriver on it, to be sure we can call SendDriverMessage on the
66 * hDrvr handle.
68 *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, NULL, hinstModule);
70 /* FIXME: lParam, dwPriority and fdwAdd ignored */
72 return MMSYSERR_NOERROR;
75 /***********************************************************************
76 * acmDriverAddW (MSACM32.@)
77 * FIXME
78 * Not implemented
80 MMRESULT WINAPI acmDriverAddW(PHACMDRIVERID phadid, HINSTANCE hinstModule,
81 LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
83 FIXME("(%p, %p, %ld, %ld, %ld): stub\n",
84 phadid, hinstModule, lParam, dwPriority, fdwAdd);
86 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
87 return MMSYSERR_ERROR;
90 /***********************************************************************
91 * acmDriverClose (MSACM32.@)
93 MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
95 PWINE_ACMDRIVER pad;
96 PWINE_ACMDRIVERID padid;
97 PWINE_ACMDRIVER* tpad;
99 if (fdwClose)
100 return MMSYSERR_INVALFLAG;
102 pad = MSACM_GetDriver(had);
103 if (!pad)
104 return MMSYSERR_INVALHANDLE;
106 padid = pad->obj.pACMDriverID;
108 /* remove driver from list */
109 for (tpad = &(padid->pACMDriverList); *tpad; *tpad = (*tpad)->pNextACMDriver) {
110 if (*tpad == pad) {
111 *tpad = (*tpad)->pNextACMDriver;
112 break;
116 /* close driver if it has been opened */
117 if (pad->hDrvr && !padid->hInstModule)
118 CloseDriver(pad->hDrvr, 0, 0);
120 HeapFree(MSACM_hHeap, 0, pad);
122 return MMSYSERR_NOERROR;
125 /***********************************************************************
126 * acmDriverDetailsA (MSACM32.@)
128 MMRESULT WINAPI acmDriverDetailsA(HACMDRIVERID hadid, PACMDRIVERDETAILSA padd, DWORD fdwDetails)
130 MMRESULT mmr;
131 ACMDRIVERDETAILSW addw;
133 addw.cbStruct = sizeof(addw);
134 mmr = acmDriverDetailsW(hadid, &addw, fdwDetails);
135 if (mmr == 0) {
136 padd->fccType = addw.fccType;
137 padd->fccComp = addw.fccComp;
138 padd->wMid = addw.wMid;
139 padd->wPid = addw.wPid;
140 padd->vdwACM = addw.vdwACM;
141 padd->vdwDriver = addw.vdwDriver;
142 padd->fdwSupport = addw.fdwSupport;
143 padd->cFormatTags = addw.cFormatTags;
144 padd->cFilterTags = addw.cFilterTags;
145 padd->hicon = addw.hicon;
146 WideCharToMultiByte( CP_ACP, 0, addw.szShortName, -1, padd->szShortName,
147 sizeof(padd->szShortName), NULL, NULL );
148 WideCharToMultiByte( CP_ACP, 0, addw.szLongName, -1, padd->szLongName,
149 sizeof(padd->szLongName), NULL, NULL );
150 WideCharToMultiByte( CP_ACP, 0, addw.szCopyright, -1, padd->szCopyright,
151 sizeof(padd->szCopyright), NULL, NULL );
152 WideCharToMultiByte( CP_ACP, 0, addw.szLicensing, -1, padd->szLicensing,
153 sizeof(padd->szLicensing), NULL, NULL );
154 WideCharToMultiByte( CP_ACP, 0, addw.szFeatures, -1, padd->szFeatures,
155 sizeof(padd->szFeatures), NULL, NULL );
157 return mmr;
160 /***********************************************************************
161 * acmDriverDetailsW (MSACM32.@)
163 MMRESULT WINAPI acmDriverDetailsW(HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, DWORD fdwDetails)
165 HACMDRIVER acmDrvr;
166 MMRESULT mmr;
168 if (fdwDetails)
169 return MMSYSERR_INVALFLAG;
171 mmr = acmDriverOpen(&acmDrvr, hadid, 0);
172 if (mmr == MMSYSERR_NOERROR) {
173 mmr = (MMRESULT)MSACM_Message(acmDrvr, ACMDM_DRIVER_DETAILS, (LPARAM)padd, 0);
175 acmDriverClose(acmDrvr, 0);
178 return mmr;
181 /***********************************************************************
182 * acmDriverEnum (MSACM32.@)
184 MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)
186 PWINE_ACMDRIVERID padid;
187 DWORD fdwSupport;
189 if (!fnCallback) return MMSYSERR_INVALPARAM;
191 if (fdwEnum & ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED))
192 return MMSYSERR_INVALFLAG;
194 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
195 fdwSupport = padid->fdwSupport;
197 if (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) {
198 if (fdwEnum & ACM_DRIVERENUMF_DISABLED)
199 fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
200 else
201 continue;
203 if (!(*fnCallback)((HACMDRIVERID)padid, dwInstance, fdwSupport))
204 break;
207 return MMSYSERR_NOERROR;
210 /***********************************************************************
211 * acmDriverID (MSACM32.@)
213 MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID)
215 PWINE_ACMOBJ pao;
217 if (!phadid)
218 return MMSYSERR_INVALPARAM;
220 if (fdwDriverID)
221 return MMSYSERR_INVALFLAG;
223 pao = MSACM_GetObj(hao, WINE_ACMOBJ_DONTCARE);
224 if (!pao)
225 return MMSYSERR_INVALHANDLE;
227 *phadid = (HACMDRIVERID) pao->pACMDriverID;
229 return MMSYSERR_NOERROR;
232 /***********************************************************************
233 * acmDriverMessage (MSACM32.@)
236 LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
238 if ((uMsg >= ACMDM_USER && uMsg < ACMDM_RESERVED_LOW) ||
239 uMsg == ACMDM_DRIVER_ABOUT ||
240 uMsg == DRV_QUERYCONFIGURE ||
241 uMsg == DRV_CONFIGURE)
242 return MSACM_Message(had, uMsg, lParam1, lParam2);
243 return MMSYSERR_INVALPARAM;
246 /***********************************************************************
247 * acmDriverOpen (MSACM32.@)
249 MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
251 PWINE_ACMDRIVERID padid;
252 PWINE_ACMDRIVER pad = NULL;
253 MMRESULT ret;
255 TRACE("(%p, %p, %08lu)\n", phad, hadid, fdwOpen);
257 if (!phad)
258 return MMSYSERR_INVALPARAM;
260 if (fdwOpen)
261 return MMSYSERR_INVALFLAG;
263 padid = MSACM_GetDriverID(hadid);
264 if (!padid)
265 return MMSYSERR_INVALHANDLE;
267 pad = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
268 if (!pad)
269 return MMSYSERR_NOMEM;
271 pad->obj.dwType = WINE_ACMOBJ_DRIVER;
272 pad->obj.pACMDriverID = padid;
274 if (!(pad->hDrvr = (HDRVR)padid->hInstModule))
276 ACMDRVOPENDESCW adod;
277 int len;
279 /* this is not an externally added driver... need to actually load it */
280 if (!padid->pszDriverAlias)
282 ret = MMSYSERR_ERROR;
283 goto gotError;
286 adod.cbStruct = sizeof(adod);
287 adod.fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
288 adod.fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
289 adod.dwVersion = acmGetVersion();
290 adod.dwFlags = fdwOpen;
291 adod.dwError = 0;
292 len = strlen("Drivers32") + 1;
293 adod.pszSectionName = HeapAlloc(MSACM_hHeap, 0, len * sizeof(WCHAR));
294 MultiByteToWideChar(CP_ACP, 0, "Drivers32", -1, (LPWSTR)adod.pszSectionName, len);
295 len = strlen(padid->pszDriverAlias) + 1;
296 adod.pszAliasName = HeapAlloc(MSACM_hHeap, 0, len * sizeof(WCHAR));
297 MultiByteToWideChar(CP_ACP, 0, padid->pszDriverAlias, -1, (LPWSTR)adod.pszAliasName, len);
298 adod.dnDevNode = 0;
300 pad->hDrvr = OpenDriverA(padid->pszDriverAlias, NULL, (DWORD)&adod);
302 HeapFree(MSACM_hHeap, 0, (LPWSTR)adod.pszSectionName);
303 HeapFree(MSACM_hHeap, 0, (LPWSTR)adod.pszAliasName);
304 if (!pad->hDrvr)
306 ret = adod.dwError;
307 goto gotError;
311 /* insert new pad at beg of list */
312 pad->pNextACMDriver = padid->pACMDriverList;
313 padid->pACMDriverList = pad;
315 /* FIXME: Create a WINE_ACMDRIVER32 */
316 *phad = (HACMDRIVER)pad;
317 TRACE("'%s' => %08lx\n", padid->pszDriverAlias, (DWORD)pad);
319 return MMSYSERR_NOERROR;
320 gotError:
321 if (pad && !pad->hDrvr)
322 HeapFree(MSACM_hHeap, 0, pad);
323 return ret;
326 /***********************************************************************
327 * acmDriverPriority (MSACM32.@)
329 MMRESULT WINAPI acmDriverPriority(HACMDRIVERID hadid, DWORD dwPriority, DWORD fdwPriority)
331 PWINE_ACMDRIVERID padid;
332 CHAR szSubKey[17];
333 CHAR szBuffer[256];
334 LONG lBufferLength = sizeof(szBuffer);
335 LONG lError;
336 HKEY hPriorityKey;
337 DWORD dwPriorityCounter;
339 padid = MSACM_GetDriverID(hadid);
340 if (!padid)
341 return MMSYSERR_INVALHANDLE;
343 /* Check for unknown flags */
344 if (fdwPriority &
345 ~(ACM_DRIVERPRIORITYF_ENABLE|ACM_DRIVERPRIORITYF_DISABLE|
346 ACM_DRIVERPRIORITYF_BEGIN|ACM_DRIVERPRIORITYF_END))
347 return MMSYSERR_INVALFLAG;
349 /* Check for incompatible flags */
350 if ((fdwPriority & ACM_DRIVERPRIORITYF_ENABLE) &&
351 (fdwPriority & ACM_DRIVERPRIORITYF_DISABLE))
352 return MMSYSERR_INVALFLAG;
354 /* Check for incompatible flags */
355 if ((fdwPriority & ACM_DRIVERPRIORITYF_BEGIN) &&
356 (fdwPriority & ACM_DRIVERPRIORITYF_END))
357 return MMSYSERR_INVALFLAG;
359 lError = RegOpenKeyA(HKEY_CURRENT_USER,
360 "Software\\Microsoft\\Multimedia\\"
361 "Audio Compression Manager\\Priority v4.00",
362 &hPriorityKey
364 /* FIXME: Create key */
365 if (lError != ERROR_SUCCESS)
366 return MMSYSERR_ERROR;
368 for (dwPriorityCounter = 1; ; dwPriorityCounter++) {
369 snprintf(szSubKey, 17, "Priority%ld", dwPriorityCounter);
370 lError = RegQueryValueA(hPriorityKey, szSubKey, szBuffer, &lBufferLength);
371 if (lError != ERROR_SUCCESS)
372 break;
374 FIXME("(%p, %ld, %ld): stub (partial)\n",
375 hadid, dwPriority, fdwPriority);
376 break;
379 RegCloseKey(hPriorityKey);
381 return MMSYSERR_ERROR;
384 /***********************************************************************
385 * acmDriverRemove (MSACM32.@)
387 MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
389 PWINE_ACMDRIVERID padid;
391 padid = MSACM_GetDriverID(hadid);
392 if (!padid)
393 return MMSYSERR_INVALHANDLE;
395 if (fdwRemove)
396 return MMSYSERR_INVALFLAG;
398 MSACM_UnregisterDriver(padid);
400 return MMSYSERR_NOERROR;