Added support for registry values larger than the server buffer.
[wine] / dlls / msacm32 / 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
10 #include "winbase.h"
11 #include "winerror.h"
12 #include "windef.h"
13 #include "wingdi.h"
14 #include "winuser.h"
15 #include "debugtools.h"
16 #include "driver.h"
17 #include "heap.h"
18 #include "mmsystem.h"
19 #include "msacm.h"
20 #include "msacmdrv.h"
21 #include "wineacm.h"
22 #include "winreg.h"
23
24 DEFAULT_DEBUG_CHANNEL(msacm)
25         
26 /***********************************************************************
27  *           acmDriverAddA (MSACM32.2)
28  */
29 MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule,
30                               LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
31 {
32     if (!phadid)
33         return MMSYSERR_INVALPARAM;
34     
35     /* Check if any unknown flags */
36     if (fdwAdd & 
37         ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND|
38           ACM_DRIVERADDF_GLOBAL))
39         return MMSYSERR_INVALFLAG;
40     
41     /* Check if any incompatible flags */
42     if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) && 
43         (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND))
44         return MMSYSERR_INVALFLAG;
45     
46     /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a 
47      * LoadDriver on it, to be sure we can call SendDriverMessage on the
48      * hDrvr handle.
49      */
50     *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, NULL, hinstModule);
51     
52     /* FIXME: lParam, dwPriority and fdwAdd ignored */
53     
54     return MMSYSERR_NOERROR;
55 }
56
57 /***********************************************************************
58  *           acmDriverAddW (MSACM32.3)
59  * FIXME
60  *   Not implemented
61  */
62 MMRESULT WINAPI acmDriverAddW(PHACMDRIVERID phadid, HINSTANCE hinstModule,
63                               LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
64 {
65     FIXME("(%p, 0x%08x, %ld, %ld, %ld): stub\n",
66           phadid, hinstModule, lParam, dwPriority, fdwAdd);
67     
68     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
69     return MMSYSERR_ERROR;
70 }
71
72 /***********************************************************************
73  *           acmDriverClose (MSACM32.4)
74  */
75 MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
76 {
77     PWINE_ACMDRIVER  p;
78     PWINE_ACMDRIVER* tp;
79     
80     if (fdwClose)
81         return MMSYSERR_INVALFLAG;
82     
83     p = MSACM_GetDriver(had);
84     if (!p)
85         return MMSYSERR_INVALHANDLE;
86
87     for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) {
88         if (*tp == p) {
89             *tp = (*tp)->pNextACMDriver;
90             break;
91         }
92     }
93     
94     if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList)
95         CloseDriver(p->hDrvr, 0, 0);
96     
97     HeapFree(MSACM_hHeap, 0, p);
98     
99     return MMSYSERR_NOERROR;
100 }
101
102 /***********************************************************************
103  *           acmDriverDetailsA (MSACM32.5)
104  */
105 MMRESULT WINAPI acmDriverDetailsA(HACMDRIVERID hadid, PACMDRIVERDETAILSA padd, DWORD fdwDetails)
106 {
107     MMRESULT mmr;
108     ACMDRIVERDETAILSW   addw;
109     
110     addw.cbStruct = sizeof(addw);
111     mmr = acmDriverDetailsW(hadid, &addw, fdwDetails);
112     if (mmr == 0) {
113         padd->fccType = addw.fccType; 
114         padd->fccComp = addw.fccComp; 
115         padd->wMid = addw.wMid; 
116         padd->wPid = addw.wPid; 
117         padd->vdwACM = addw.vdwACM; 
118         padd->vdwDriver = addw.vdwDriver; 
119         padd->fdwSupport = addw.fdwSupport; 
120         padd->cFormatTags = addw.cFormatTags; 
121         padd->cFilterTags = addw.cFilterTags; 
122         padd->hicon = addw.hicon; 
123         lstrcpyWtoA(padd->szShortName, addw.szShortName);
124         lstrcpyWtoA(padd->szLongName, addw.szLongName);
125         lstrcpyWtoA(padd->szCopyright, addw.szCopyright);
126         lstrcpyWtoA(padd->szLicensing, addw.szLicensing);
127         lstrcpyWtoA(padd->szFeatures, addw.szFeatures);
128     }
129     return mmr;
130 }
131
132 /***********************************************************************
133  *           acmDriverDetailsW (MSACM32.6)
134  */
135 MMRESULT WINAPI acmDriverDetailsW(HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, DWORD fdwDetails)
136 {
137     HACMDRIVER acmDrvr;
138     MMRESULT mmr;
139     
140     if (fdwDetails)
141         return MMSYSERR_INVALFLAG;
142     
143     mmr = acmDriverOpen(&acmDrvr, hadid, 0);
144     if (mmr == 0) {
145         mmr = (MMRESULT)acmDriverMessage(acmDrvr, ACMDM_DRIVER_DETAILS, (LPARAM) padd,  0);
146     
147         acmDriverClose(acmDrvr, 0);
148     }
149     
150     return mmr;
151 }
152
153 /***********************************************************************
154  *           acmDriverEnum (MSACM32.7)
155  */
156 MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)
157 {
158     PWINE_ACMDRIVERID   p;
159     DWORD               fdwSupport;
160
161     if (!fnCallback) {
162         return MMSYSERR_INVALPARAM;
163     }
164     
165     if (fdwEnum && ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) {
166         return MMSYSERR_INVALFLAG;
167     }
168     
169     for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) {
170         fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
171         if (!p->bEnabled) {
172             if (fdwEnum & ACM_DRIVERENUMF_DISABLED)
173                 fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
174             else
175                 continue;
176         }
177         (*fnCallback)((HACMDRIVERID) p, dwInstance, fdwSupport);
178     }
179     
180     return MMSYSERR_NOERROR;
181 }
182
183 /***********************************************************************
184  *           acmDriverID (MSACM32.8)
185  */
186 MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID)
187 {
188     PWINE_ACMOBJ pao;
189     
190     pao = MSACM_GetObj(hao);
191     if (!pao)
192         return MMSYSERR_INVALHANDLE;
193     
194     if (!phadid)
195         return MMSYSERR_INVALPARAM;
196     
197     if (fdwDriverID)
198         return MMSYSERR_INVALFLAG;
199     
200     *phadid = (HACMDRIVERID) pao->pACMDriverID;
201     
202     return MMSYSERR_NOERROR;
203 }
204
205 /***********************************************************************
206  *           acmDriverMessage (MSACM32.9)
207  * FIXME
208  *   Not implemented
209  */
210 LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
211 {
212     PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
213     if (!pad)
214         return MMSYSERR_INVALPARAM;
215     
216     /* FIXME: Check if uMsg legal */
217     
218     if (!SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2))
219         return MMSYSERR_NOTSUPPORTED;
220     
221     return MMSYSERR_NOERROR;
222 }
223
224
225 /***********************************************************************
226  *           acmDriverOpen (MSACM32.10)
227  */
228 MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
229 {
230     PWINE_ACMDRIVERID   padid;
231     PWINE_ACMDRIVER     pad;
232
233     TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen);
234
235     if (!phad)
236         return MMSYSERR_INVALPARAM;
237     
238     padid = MSACM_GetDriverID(hadid); 
239     if (!padid)
240         return MMSYSERR_INVALHANDLE;
241     
242     if (fdwOpen)
243         return MMSYSERR_INVALFLAG;
244     
245     pad = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
246     if (!pad) return MMSYSERR_NOMEM;
247
248     pad->obj.pACMDriverID = padid;
249     
250     if (!padid->hInstModule)
251         pad->hDrvr = OpenDriverA(padid->pszDriverAlias, "drivers32", 0);
252     else
253         pad->hDrvr = padid->hInstModule;
254     
255     if (!pad->hDrvr) {
256         HeapFree(MSACM_hHeap, 0, pad);
257         return MMSYSERR_ERROR;
258     }
259     
260     pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc");
261
262     /* insert new pad at beg of list */
263     pad->pNextACMDriver = padid->pACMDriverList;
264     padid->pACMDriverList = pad;
265
266     /* FIXME: Create a WINE_ACMDRIVER32 */
267     *phad = (HACMDRIVER)pad;
268     
269     return MMSYSERR_NOERROR;
270 }
271
272 /***********************************************************************
273  *           acmDriverPriority (MSACM32.11)
274  */
275 MMRESULT WINAPI acmDriverPriority(HACMDRIVERID hadid, DWORD dwPriority, DWORD fdwPriority)
276 {
277     PWINE_ACMDRIVERID padid;
278     CHAR szSubKey[17];
279     CHAR szBuffer[256];
280     LONG lBufferLength = sizeof(szBuffer);
281     LONG lError;
282     HKEY hPriorityKey;
283     DWORD dwPriorityCounter;
284     
285     padid = MSACM_GetDriverID(hadid);
286     if (!padid)
287         return MMSYSERR_INVALHANDLE;
288     
289     /* Check for unknown flags */
290     if (fdwPriority & 
291         ~(ACM_DRIVERPRIORITYF_ENABLE|ACM_DRIVERPRIORITYF_DISABLE|
292           ACM_DRIVERPRIORITYF_BEGIN|ACM_DRIVERPRIORITYF_END))
293         return MMSYSERR_INVALFLAG;
294     
295     /* Check for incompatible flags */
296     if ((fdwPriority & ACM_DRIVERPRIORITYF_ENABLE) &&
297         (fdwPriority & ACM_DRIVERPRIORITYF_DISABLE))
298         return MMSYSERR_INVALFLAG;
299     
300     /* Check for incompatible flags */
301     if ((fdwPriority & ACM_DRIVERPRIORITYF_BEGIN) &&
302         (fdwPriority & ACM_DRIVERPRIORITYF_END))
303         return MMSYSERR_INVALFLAG;
304     
305     lError = RegOpenKeyA(HKEY_CURRENT_USER, 
306                          "Software\\Microsoft\\Multimedia\\"
307                          "Audio Compression Manager\\Priority v4.00",
308                          &hPriorityKey
309                          );
310     /* FIXME: Create key */
311     if (lError != ERROR_SUCCESS)
312         return MMSYSERR_ERROR;
313     
314     for (dwPriorityCounter = 1; ; dwPriorityCounter++)  {
315         wsnprintfA(szSubKey, 17, "Priorty%ld", dwPriorityCounter);
316         lError = RegQueryValueA(hPriorityKey, szSubKey, szBuffer, &lBufferLength);
317         if (lError != ERROR_SUCCESS)
318             break;
319         
320         FIXME("(0x%08x, %ld, %ld): stub (partial)\n", 
321               hadid, dwPriority, fdwPriority);
322         break;
323     }
324     
325     RegCloseKey(hPriorityKey);
326     
327     return MMSYSERR_ERROR;
328 }
329
330 /***********************************************************************
331  *           acmDriverRemove (MSACM32.12)
332  */
333 MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
334 {
335     PWINE_ACMDRIVERID padid;
336     
337     padid = MSACM_GetDriverID(hadid);
338     if (!padid)
339         return MMSYSERR_INVALHANDLE;
340     
341     if (fdwRemove)
342         return MMSYSERR_INVALFLAG;
343     
344     MSACM_UnregisterDriver(padid);
345     
346     return MMSYSERR_NOERROR;
347 }
348