Changed the GDI driver interface to pass an opaque PHYSDEV pointer
[wine] / dlls / msacm / driver.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 <stdio.h>
25
26 #include "winbase.h"
27 #include "winerror.h"
28 #include "windef.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "winnls.h"
32 #include "mmsystem.h"
33 #include "msacm.h"
34 #include "msacmdrv.h"
35 #include "wineacm.h"
36 #include "winreg.h"
37 #include "wine/debug.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(msacm);
40         
41 /***********************************************************************
42  *           acmDriverAddA (MSACM32.@)
43  */
44 MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule,
45                               LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
46 {
47     if (!phadid)
48         return MMSYSERR_INVALPARAM;
49     
50     /* Check if any unknown flags */
51     if (fdwAdd & 
52         ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND|
53           ACM_DRIVERADDF_GLOBAL))
54         return MMSYSERR_INVALFLAG;
55     
56     /* Check if any incompatible flags */
57     if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) && 
58         (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND))
59         return MMSYSERR_INVALFLAG;
60     
61     /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a 
62      * LoadDriver on it, to be sure we can call SendDriverMessage on the
63      * hDrvr handle.
64      */
65     *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, NULL, hinstModule);
66     
67     /* FIXME: lParam, dwPriority and fdwAdd ignored */
68     
69     return MMSYSERR_NOERROR;
70 }
71
72 /***********************************************************************
73  *           acmDriverAddW (MSACM32.@)
74  * FIXME
75  *   Not implemented
76  */
77 MMRESULT WINAPI acmDriverAddW(PHACMDRIVERID phadid, HINSTANCE hinstModule,
78                               LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
79 {
80     FIXME("(%p, 0x%08x, %ld, %ld, %ld): stub\n",
81           phadid, hinstModule, lParam, dwPriority, fdwAdd);
82     
83     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
84     return MMSYSERR_ERROR;
85 }
86
87 /***********************************************************************
88  *           acmDriverClose (MSACM32.@)
89  */
90 MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
91 {
92     PWINE_ACMDRIVER     pad;
93     PWINE_ACMDRIVERID   padid;
94     PWINE_ACMDRIVER*    tpad;
95
96     if (fdwClose)
97         return MMSYSERR_INVALFLAG;
98     
99     pad = MSACM_GetDriver(had);
100     if (!pad)
101         return MMSYSERR_INVALHANDLE;
102
103     padid = pad->obj.pACMDriverID;
104
105     /* remove driver from list */
106     for (tpad = &(padid->pACMDriverList); *tpad; *tpad = (*tpad)->pNextACMDriver) {
107         if (*tpad == pad) {
108             *tpad = (*tpad)->pNextACMDriver;
109             break;
110         }
111     }
112     
113     /* close driver if it has been opened */
114     if (pad->hDrvr && !padid->hInstModule)
115         CloseDriver(pad->hDrvr, 0, 0);
116     
117     HeapFree(MSACM_hHeap, 0, pad);
118     
119     return MMSYSERR_NOERROR;
120 }
121
122 /***********************************************************************
123  *           acmDriverDetailsA (MSACM32.@)
124  */
125 MMRESULT WINAPI acmDriverDetailsA(HACMDRIVERID hadid, PACMDRIVERDETAILSA padd, DWORD fdwDetails)
126 {
127     MMRESULT mmr;
128     ACMDRIVERDETAILSW   addw;
129     
130     addw.cbStruct = sizeof(addw);
131     mmr = acmDriverDetailsW(hadid, &addw, fdwDetails);
132     if (mmr == 0) {
133         padd->fccType = addw.fccType; 
134         padd->fccComp = addw.fccComp; 
135         padd->wMid = addw.wMid; 
136         padd->wPid = addw.wPid; 
137         padd->vdwACM = addw.vdwACM; 
138         padd->vdwDriver = addw.vdwDriver; 
139         padd->fdwSupport = addw.fdwSupport; 
140         padd->cFormatTags = addw.cFormatTags; 
141         padd->cFilterTags = addw.cFilterTags; 
142         padd->hicon = addw.hicon; 
143         WideCharToMultiByte( CP_ACP, 0, addw.szShortName, -1, padd->szShortName,
144                              sizeof(padd->szShortName), NULL, NULL );
145         WideCharToMultiByte( CP_ACP, 0, addw.szLongName, -1, padd->szLongName,
146                              sizeof(padd->szLongName), NULL, NULL );
147         WideCharToMultiByte( CP_ACP, 0, addw.szCopyright, -1, padd->szCopyright,
148                              sizeof(padd->szCopyright), NULL, NULL );
149         WideCharToMultiByte( CP_ACP, 0, addw.szLicensing, -1, padd->szLicensing,
150                              sizeof(padd->szLicensing), NULL, NULL );
151         WideCharToMultiByte( CP_ACP, 0, addw.szFeatures, -1, padd->szFeatures,
152                              sizeof(padd->szFeatures), NULL, NULL );
153     }
154     return mmr;
155 }
156
157 /***********************************************************************
158  *           acmDriverDetailsW (MSACM32.@)
159  */
160 MMRESULT WINAPI acmDriverDetailsW(HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, DWORD fdwDetails)
161 {
162     HACMDRIVER acmDrvr;
163     MMRESULT mmr;
164     
165     if (fdwDetails)
166         return MMSYSERR_INVALFLAG;
167     
168     mmr = acmDriverOpen(&acmDrvr, hadid, 0);
169     if (mmr == MMSYSERR_NOERROR) {
170         mmr = (MMRESULT)MSACM_Message(acmDrvr, ACMDM_DRIVER_DETAILS, (LPARAM)padd,  0);
171     
172         acmDriverClose(acmDrvr, 0);
173     }
174     
175     return mmr;
176 }
177
178 /***********************************************************************
179  *           acmDriverEnum (MSACM32.@)
180  */
181 MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)
182 {
183     PWINE_ACMDRIVERID   padid;
184     DWORD               fdwSupport;
185
186     if (!fnCallback) return MMSYSERR_INVALPARAM;
187     
188     if (fdwEnum & ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED))
189         return MMSYSERR_INVALFLAG;
190     
191     for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
192         fdwSupport = padid->fdwSupport;
193         
194         if (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) {
195             if (fdwEnum & ACM_DRIVERENUMF_DISABLED)
196                 fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
197             else
198                 continue;
199         }
200         if (!(*fnCallback)((HACMDRIVERID)padid, dwInstance, fdwSupport))
201             break;
202     }
203     
204     return MMSYSERR_NOERROR;
205 }
206
207 /***********************************************************************
208  *           acmDriverID (MSACM32.@)
209  */
210 MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID)
211 {
212     PWINE_ACMOBJ pao;
213     
214     if (!phadid)
215         return MMSYSERR_INVALPARAM;
216     
217     if (fdwDriverID)
218         return MMSYSERR_INVALFLAG;
219     
220     pao = MSACM_GetObj(hao, WINE_ACMOBJ_DONTCARE);
221     if (!pao)
222         return MMSYSERR_INVALHANDLE;
223     
224     *phadid = (HACMDRIVERID) pao->pACMDriverID;
225     
226     return MMSYSERR_NOERROR;
227 }
228
229 /***********************************************************************
230  *           acmDriverMessage (MSACM32.@)
231  *
232  */
233 LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
234 {
235     if ((uMsg >= ACMDM_USER && uMsg < ACMDM_RESERVED_LOW) ||
236         uMsg == ACMDM_DRIVER_ABOUT ||
237         uMsg == DRV_QUERYCONFIGURE ||
238         uMsg == DRV_CONFIGURE)
239         return MSACM_Message(had, uMsg, lParam1, lParam2);
240     return MMSYSERR_INVALPARAM;
241 }
242
243 static  MMRESULT        MSACM_DriverOpenHelper(PWINE_ACMDRIVER* ppad, PWINE_ACMDRIVERID padid, DWORD fdwOpen, BOOL useDesc)
244 {
245     MMRESULT            ret = MMSYSERR_ERROR;
246     PWINE_ACMDRIVER     pad;
247
248     *ppad = NULL;
249
250     pad = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
251     if (!pad) return MMSYSERR_NOMEM;
252
253     pad->obj.dwType = WINE_ACMOBJ_DRIVER;
254     pad->obj.pACMDriverID = padid;
255
256     if (!(pad->hDrvr = padid->hInstModule)) {
257         /* this is not an externally added driver... need to load it */
258         if (!padid->pszDriverAlias) goto gotError;
259
260         if (useDesc) {
261             ACMDRVOPENDESCW     adod;
262             int                 len;
263
264             adod.cbStruct = sizeof(adod);
265             adod.fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
266             adod.fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
267             adod.dwVersion = acmGetVersion();
268             adod.dwFlags = fdwOpen;
269             adod.dwError = 0;
270             len = strlen("Drivers32") + 1;
271             adod.pszSectionName = HeapAlloc(MSACM_hHeap, 0, len * sizeof(WCHAR));
272             MultiByteToWideChar(CP_ACP, 0, "Drivers32", -1, (LPWSTR)adod.pszSectionName, len);
273             len = strlen(padid->pszDriverAlias) + 1;
274             adod.pszAliasName = HeapAlloc(MSACM_hHeap, 0, len * sizeof(WCHAR));
275             MultiByteToWideChar(CP_ACP, 0, padid->pszDriverAlias, -1, (LPWSTR)adod.pszAliasName, len);
276             adod.dnDevNode = 0;
277
278             pad->hDrvr = OpenDriverA(padid->pszDriverAlias, NULL, (DWORD)&adod);
279
280             HeapFree(MSACM_hHeap, 0, (LPWSTR)adod.pszSectionName);
281             HeapFree(MSACM_hHeap, 0, (LPWSTR)adod.pszAliasName);
282             if (!pad->hDrvr) {
283                 ret = adod.dwError;
284                 goto gotError;
285             }
286         } else {
287             if (!(pad->hDrvr = OpenDriverA(padid->pszDriverAlias, 0L, 0L))) {
288                 ret = MMSYSERR_ERROR;
289                 goto gotError;
290             }
291         }
292     }
293     *ppad = pad;
294     return MMSYSERR_NOERROR;
295  gotError:
296     HeapFree(MSACM_hHeap, 0, pad);
297     return ret;
298 }
299
300 /***********************************************************************
301  *           acmDriverOpen (MSACM32.@)
302  */
303 MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
304 {
305     PWINE_ACMDRIVERID   padid;
306     PWINE_ACMDRIVER     pad = NULL, first_pad = NULL;
307     MMRESULT            ret;
308
309     TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen);
310
311     if (!phad)
312         return MMSYSERR_INVALPARAM;
313     
314     if (fdwOpen)
315         return MMSYSERR_INVALFLAG;
316     
317     padid = MSACM_GetDriverID(hadid); 
318     if (!padid)
319         return MMSYSERR_INVALHANDLE;
320
321     /* first driver to be loaded ? */
322     if (!padid->pACMDriverList && !padid->hInstModule) {
323         ret = MSACM_DriverOpenHelper(&first_pad, padid, fdwOpen, FALSE);
324         if (ret) goto gotError;
325
326         
327         /* insert new pad at beg of list */
328         first_pad->pNextACMDriver = NULL;
329         padid->pACMDriverList = first_pad;
330     }
331
332     ret = MSACM_DriverOpenHelper(&pad, padid, fdwOpen, TRUE);
333     if (ret) {
334         if (first_pad)
335             acmDriverClose((HACMDRIVER)first_pad, 0L);
336         goto gotError;
337     }
338
339     /* insert new pad at beg of list */
340     pad->pNextACMDriver = padid->pACMDriverList;
341     padid->pACMDriverList = pad;
342
343     /* FIXME: Create a WINE_ACMDRIVER32 */
344     *phad = (HACMDRIVER)pad;
345     TRACE("'%s' => %08lx\n", padid->pszDriverAlias, (DWORD)pad);
346
347     return MMSYSERR_NOERROR;
348  gotError:
349     if (pad && !pad->hDrvr)
350         HeapFree(MSACM_hHeap, 0, pad);
351     return ret;
352 }
353
354 /***********************************************************************
355  *           acmDriverPriority (MSACM32.@)
356  */
357 MMRESULT WINAPI acmDriverPriority(HACMDRIVERID hadid, DWORD dwPriority, DWORD fdwPriority)
358 {
359     PWINE_ACMDRIVERID padid;
360     CHAR szSubKey[17];
361     CHAR szBuffer[256];
362     LONG lBufferLength = sizeof(szBuffer);
363     LONG lError;
364     HKEY hPriorityKey;
365     DWORD dwPriorityCounter;
366     
367     padid = MSACM_GetDriverID(hadid);
368     if (!padid)
369         return MMSYSERR_INVALHANDLE;
370     
371     /* Check for unknown flags */
372     if (fdwPriority & 
373         ~(ACM_DRIVERPRIORITYF_ENABLE|ACM_DRIVERPRIORITYF_DISABLE|
374           ACM_DRIVERPRIORITYF_BEGIN|ACM_DRIVERPRIORITYF_END))
375         return MMSYSERR_INVALFLAG;
376     
377     /* Check for incompatible flags */
378     if ((fdwPriority & ACM_DRIVERPRIORITYF_ENABLE) &&
379         (fdwPriority & ACM_DRIVERPRIORITYF_DISABLE))
380         return MMSYSERR_INVALFLAG;
381     
382     /* Check for incompatible flags */
383     if ((fdwPriority & ACM_DRIVERPRIORITYF_BEGIN) &&
384         (fdwPriority & ACM_DRIVERPRIORITYF_END))
385         return MMSYSERR_INVALFLAG;
386     
387     lError = RegOpenKeyA(HKEY_CURRENT_USER, 
388                          "Software\\Microsoft\\Multimedia\\"
389                          "Audio Compression Manager\\Priority v4.00",
390                          &hPriorityKey
391                          );
392     /* FIXME: Create key */
393     if (lError != ERROR_SUCCESS)
394         return MMSYSERR_ERROR;
395     
396     for (dwPriorityCounter = 1; ; dwPriorityCounter++)  {
397         snprintf(szSubKey, 17, "Priorty%ld", dwPriorityCounter);
398         lError = RegQueryValueA(hPriorityKey, szSubKey, szBuffer, &lBufferLength);
399         if (lError != ERROR_SUCCESS)
400             break;
401         
402         FIXME("(0x%08x, %ld, %ld): stub (partial)\n", 
403               hadid, dwPriority, fdwPriority);
404         break;
405     }
406     
407     RegCloseKey(hPriorityKey);
408     
409     return MMSYSERR_ERROR;
410 }
411
412 /***********************************************************************
413  *           acmDriverRemove (MSACM32.@)
414  */
415 MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
416 {
417     PWINE_ACMDRIVERID padid;
418     
419     padid = MSACM_GetDriverID(hadid);
420     if (!padid)
421         return MMSYSERR_INVALHANDLE;
422     
423     if (fdwRemove)
424         return MMSYSERR_INVALFLAG;
425     
426     MSACM_UnregisterDriver(padid);
427     
428     return MMSYSERR_NOERROR;
429 }
430