Better implementation of GetCalendarInfo{A,W}, not perfect.
[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 /***********************************************************************
244  *           acmDriverOpen (MSACM32.@)
245  */
246 MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
247 {
248     PWINE_ACMDRIVERID   padid;
249     PWINE_ACMDRIVER     pad = NULL;
250     MMRESULT            ret;
251
252     TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen);
253
254     if (!phad)
255         return MMSYSERR_INVALPARAM;
256     
257     if (fdwOpen)
258         return MMSYSERR_INVALFLAG;
259     
260     padid = MSACM_GetDriverID(hadid); 
261     if (!padid)
262         return MMSYSERR_INVALHANDLE;
263
264     pad = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
265     if (!pad) 
266         return MMSYSERR_NOMEM;
267
268     pad->obj.dwType = WINE_ACMOBJ_DRIVER;
269     pad->obj.pACMDriverID = padid;
270
271     if (!(pad->hDrvr = padid->hInstModule)) 
272     {
273         ACMDRVOPENDESCW adod;
274         int             len;
275
276         /* this is not an externally added driver... need to actually load it */
277         if (!padid->pszDriverAlias) 
278         {       
279             ret = MMSYSERR_ERROR;
280             goto gotError;
281         }       
282
283         adod.cbStruct = sizeof(adod);
284         adod.fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
285         adod.fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
286         adod.dwVersion = acmGetVersion();
287         adod.dwFlags = fdwOpen;
288         adod.dwError = 0;
289         len = strlen("Drivers32") + 1;
290         adod.pszSectionName = HeapAlloc(MSACM_hHeap, 0, len * sizeof(WCHAR));
291         MultiByteToWideChar(CP_ACP, 0, "Drivers32", -1, (LPWSTR)adod.pszSectionName, len);
292         len = strlen(padid->pszDriverAlias) + 1;
293         adod.pszAliasName = HeapAlloc(MSACM_hHeap, 0, len * sizeof(WCHAR));
294         MultiByteToWideChar(CP_ACP, 0, padid->pszDriverAlias, -1, (LPWSTR)adod.pszAliasName, len);
295         adod.dnDevNode = 0;
296
297         pad->hDrvr = OpenDriverA(padid->pszDriverAlias, NULL, (DWORD)&adod);
298
299         HeapFree(MSACM_hHeap, 0, (LPWSTR)adod.pszSectionName);
300         HeapFree(MSACM_hHeap, 0, (LPWSTR)adod.pszAliasName);
301         if (!pad->hDrvr) 
302         {
303             ret = adod.dwError;
304             goto gotError;
305         }
306     }
307
308     /* insert new pad at beg of list */
309     pad->pNextACMDriver = padid->pACMDriverList;
310     padid->pACMDriverList = pad;
311
312     /* FIXME: Create a WINE_ACMDRIVER32 */
313     *phad = (HACMDRIVER)pad;
314     TRACE("'%s' => %08lx\n", padid->pszDriverAlias, (DWORD)pad);
315
316     return MMSYSERR_NOERROR;
317  gotError:
318     if (pad && !pad->hDrvr)
319         HeapFree(MSACM_hHeap, 0, pad);
320     return ret;
321 }
322
323 /***********************************************************************
324  *           acmDriverPriority (MSACM32.@)
325  */
326 MMRESULT WINAPI acmDriverPriority(HACMDRIVERID hadid, DWORD dwPriority, DWORD fdwPriority)
327 {
328     PWINE_ACMDRIVERID padid;
329     CHAR szSubKey[17];
330     CHAR szBuffer[256];
331     LONG lBufferLength = sizeof(szBuffer);
332     LONG lError;
333     HKEY hPriorityKey;
334     DWORD dwPriorityCounter;
335     
336     padid = MSACM_GetDriverID(hadid);
337     if (!padid)
338         return MMSYSERR_INVALHANDLE;
339     
340     /* Check for unknown flags */
341     if (fdwPriority & 
342         ~(ACM_DRIVERPRIORITYF_ENABLE|ACM_DRIVERPRIORITYF_DISABLE|
343           ACM_DRIVERPRIORITYF_BEGIN|ACM_DRIVERPRIORITYF_END))
344         return MMSYSERR_INVALFLAG;
345     
346     /* Check for incompatible flags */
347     if ((fdwPriority & ACM_DRIVERPRIORITYF_ENABLE) &&
348         (fdwPriority & ACM_DRIVERPRIORITYF_DISABLE))
349         return MMSYSERR_INVALFLAG;
350     
351     /* Check for incompatible flags */
352     if ((fdwPriority & ACM_DRIVERPRIORITYF_BEGIN) &&
353         (fdwPriority & ACM_DRIVERPRIORITYF_END))
354         return MMSYSERR_INVALFLAG;
355     
356     lError = RegOpenKeyA(HKEY_CURRENT_USER, 
357                          "Software\\Microsoft\\Multimedia\\"
358                          "Audio Compression Manager\\Priority v4.00",
359                          &hPriorityKey
360                          );
361     /* FIXME: Create key */
362     if (lError != ERROR_SUCCESS)
363         return MMSYSERR_ERROR;
364     
365     for (dwPriorityCounter = 1; ; dwPriorityCounter++)  {
366         snprintf(szSubKey, 17, "Priorty%ld", dwPriorityCounter);
367         lError = RegQueryValueA(hPriorityKey, szSubKey, szBuffer, &lBufferLength);
368         if (lError != ERROR_SUCCESS)
369             break;
370         
371         FIXME("(0x%08x, %ld, %ld): stub (partial)\n", 
372               hadid, dwPriority, fdwPriority);
373         break;
374     }
375     
376     RegCloseKey(hPriorityKey);
377     
378     return MMSYSERR_ERROR;
379 }
380
381 /***********************************************************************
382  *           acmDriverRemove (MSACM32.@)
383  */
384 MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
385 {
386     PWINE_ACMDRIVERID padid;
387     
388     padid = MSACM_GetDriverID(hadid);
389     if (!padid)
390         return MMSYSERR_INVALHANDLE;
391     
392     if (fdwRemove)
393         return MMSYSERR_INVALFLAG;
394     
395     MSACM_UnregisterDriver(padid);
396     
397     return MMSYSERR_NOERROR;
398 }
399