blob: 15a0d2a1bba89f94fe3b953b78b2ab2d749661e4 [file] [log] [blame]
Eric Pouech4853b6d1999-09-22 16:52:47 +00001/* -*- tab-width: 8; c-basic-offset: 4 -*- */
2
3/*
4 * MMSYTEM low level drivers handling functions
5 *
6 * Copyright 1999 Eric Pouech
7 */
8
9#include <string.h>
10#include <assert.h>
11#include "heap.h"
12#include "user.h" /* should be removed asap; used in MMDRV_(Get|Alloc|Free) */
13#include "selectors.h"
14#include "driver.h"
15#include "winver.h"
16#include "module.h"
17#include "winemm.h"
18#include "debugtools.h"
19
20DEFAULT_DEBUG_CHANNEL(mmsys)
21
22typedef DWORD CALLBACK (*WINEMM_msgFunc16)(UINT16, WORD, DWORD, DWORD, DWORD);
23typedef DWORD CALLBACK (*WINEMM_msgFunc32)(UINT , UINT, DWORD, DWORD, DWORD);
24
25/* for each loaded driver and each known type of driver, this structure contains
26 * the information needed to access it
27 */
28typedef struct tagWINE_MM_DRIVER_PART {
29 int nIDMin; /* lower bound of global indexes for this type */
30 int nIDMax; /* hhigher bound of global indexes for this type */
31 union {
32 WINEMM_msgFunc32 fnMessage32; /* pointer to fonction */
33 WINEMM_msgFunc16 fnMessage16;
34 } u;
35} WINE_MM_DRIVER_PART;
36
37/* each low-level .drv will be associated with an instance of this structure */
38typedef struct tagWINE_MM_DRIVER {
39 HDRVR hDrvr; /* handle of loader driver */
40 LPSTR name; /* name of the driver */
41 BOOL bIs32 : 1, /* TRUE if 32 bit driver, FALSE for 16 */
42 bIsMapper : 1; /* TRUE if mapper */
43 WINE_MM_DRIVER_PART parts[MMDRV_MAX];/* Information for all known types */
44} WINE_MM_DRIVER, *LPWINE_MM_DRIVER;
45
46typedef enum {
47 MMDRV_MAP_NOMEM, /* ko, memory problem */
48 MMDRV_MAP_MSGERROR, /* ko, unknown message */
49 MMDRV_MAP_OK, /* ok, no memory allocated. to be sent to the proc. */
50 MMDRV_MAP_OKMEM, /* ok, some memory allocated, need to call UnMapMsg. to be sent to the proc. */
51 MMDRV_MAP_PASS /* not handled (no memory allocated) to be sent to the driver */
52} MMDRV_MapType;
53
54typedef MMDRV_MapType (*MMDRV_MAPFUNC )(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
55
56/* each known type of driver has an instance of this structure */
57typedef struct tagWINE_LLTYPE {
58 /* those attributes depend on the specification of the type */
59 LPSTR name; /* name (for debugging) */
60 BOOL bSupportMapper; /* if type is allowed to support mapper */
61 MMDRV_MAPFUNC Map16To32A; /* those are function pointers to handle */
62 MMDRV_MAPFUNC UnMap16To32A; /* the parameter conversion (16 vs 32 bit) */
63 MMDRV_MAPFUNC Map32ATo16; /* when hi-func (in mmsystem or winmm) and */
64 MMDRV_MAPFUNC UnMap32ATo16; /* low-func (in .drv) do not match */
65 LPDRVCALLBACK Callback; /* handles callback for a specified type */
66 /* those attributes reflect the loaded/current situation for the type */
67 UINT wMaxId; /* number of loaded devices (sum across all loaded drivers */
68 LPWINE_MLD lpMlds; /* "static" mlds to access the part though device IDs */
69 int nMapper; /* index to mapper */
70} WINE_LLTYPE;
71
72static WINE_MM_DRIVER MMDrvs[3];
73
74/* ### start build ### */
75extern WORD CALLBACK MMDRV_CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG);
76/* ### stop build ### */
77
78/**************************************************************************
79 * MMDRV_GetDescription16 [internal]
80 */
81static BOOL MMDRV_GetDescription16(const char* fname, char* buf, int buflen)
82{
83 OFSTRUCT ofs;
84 HFILE hFile;
85 WORD w;
86 DWORD dw;
87 BOOL ret = FALSE;
88
89 if ((hFile = OpenFile(fname, &ofs, OF_READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR) {
90 ERR("Can't open file %s\n", fname);
91 return FALSE;
92 }
93
94#define E(_x) do {TRACE _x;goto theEnd;} while(0)
95
96 if (_lread(hFile, &w, 2) != 2) E(("Can't read sig\n"));
97 if (w != ('Z' * 256 + 'M')) E(("Bad sig %04x\n", w));
98 if (_llseek(hFile, 0x3C, SEEK_SET) < 0) E(("Can't seek to ext header offset\n"));
99 if (_lread(hFile, &dw, 4) != 4) E(("Can't read ext header offset\n"));
100 if (_llseek(hFile, dw + 0x2C, SEEK_SET) < 0) E(("Can't seek to ext header.nr table %lu\n", dw+0x2C));
101 if (_lread(hFile, &dw, 4) != 4) E(("Can't read nr table offset\n"));
102 if (_llseek(hFile, dw, SEEK_SET) < 0) E(("Can't seek to nr table %lu\n", dw));
103 if (_lread(hFile, buf, 1) != 1) E(("Can't read descr length\n"));
104 buflen = MIN((BYTE)buf[0], buflen - 1);
105 if (_lread(hFile, buf, buflen) != buflen) E(("Can't read descr (%d)\n", buflen));
106 buf[buflen] = '\0';
107 ret = TRUE;
108 TRACE("Got '%s' [%d]\n", buf, buflen);
109theEnd:
110 CloseHandle(hFile);
111 return ret;
112}
113
114/**************************************************************************
115 * MMDRV_GetDescription32 [internal]
116 */
117static BOOL MMDRV_GetDescription32(const char* fname, char* buf, int buflen)
118{
119 OFSTRUCT ofs;
120 DWORD h;
121 LPVOID ptr = 0;
122 LPVOID val;
123 DWORD dw;
124 BOOL ret = FALSE;
125 UINT u;
126
127#define E(_x) do {TRACE _x;goto theEnd;} while(0)
128
129 if (OpenFile(fname, &ofs, OF_EXIST)==HFILE_ERROR) E(("Can't find file %s\n", fname));
130
131 /* should load version.dll */
132 if (!(dw = GetFileVersionInfoSizeA(ofs.szPathName, &h))) E(("Can't get FVIS\n"));
133 if (!(ptr = HeapAlloc(GetProcessHeap(), 0, dw))) E(("OOM\n"));
134 if (!GetFileVersionInfoA(ofs.szPathName, h, dw, ptr)) E(("Can't get FVI\n"));
135
136#define A(_x) if (VerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\" #_x, &val, &u)) \
137 TRACE(#_x " => %s\n", (LPSTR)val); else TRACE(#_x " @\n")
138
139 A(CompanyName);
140 A(FileDescription);
141 A(FileVersion);
142 A(InternalName);
143 A(LegalCopyright);
144 A(OriginalFilename);
145 A(ProductName);
146 A(ProductVersion);
147 A(Comments);
148 A(LegalTrademarks);
149 A(PrivateBuild);
150 A(SpecialBuild);
151#undef A
152
153 if (!VerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\ProductName", &val, &u)) E(("Can't get product name\n"));
154 strncpy(buf, val, buflen - 1);
155 buf[buflen - 1] = '\0';
156
157#undef E
158 ret = TRUE;
159theEnd:
160 HeapFree(GetProcessHeap(), 0, ptr);
161 return ret;
162}
163
164/**************************************************************************
165 * MMDRV_Callback [internal]
166 */
167static void MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD dwParam1, DWORD dwParam2)
168{
169 TRACE("CB (*%08lx)(%08x %08x %08lx %08lx %08lx\n",
170 mld->dwCallback, hDev, uMsg, mld->dwClientInstance, dwParam1, dwParam2);
171
172 if (!mld->bFrom32 && (mld->dwFlags & DCB_TYPEMASK) == DCB_FUNCTION) {
173 /* 16 bit func, call it */
174 TRACE("Function (16 bit) !\n");
175 MMDRV_CallTo16_word_wwlll((FARPROC16)mld->dwCallback, hDev, uMsg,
176 mld->dwClientInstance, dwParam1, dwParam2);
177 } else {
178 DriverCallback(mld->dwCallback, mld->dwFlags, hDev, uMsg,
179 mld->dwClientInstance, dwParam1, dwParam2);
180 }
181}
182
183/* =================================
184 * A U X M A P P E R S
185 * ================================= */
186
187/**************************************************************************
188 * MMDRV_Aux_Map16To32A [internal]
189 */
190static MMDRV_MapType MMDRV_Aux_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
191{
192 return MMDRV_MAP_MSGERROR;
193}
194
195/**************************************************************************
196 * MMDRV_Aux_UnMap16To32A [internal]
197 */
198static MMDRV_MapType MMDRV_Aux_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
199{
200 return MMDRV_MAP_MSGERROR;
201}
202
203/**************************************************************************
204 * MMDRV_Aux_Map32ATo16 [internal]
205 */
206static MMDRV_MapType MMDRV_Aux_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
207{
208 return MMDRV_MAP_MSGERROR;
209}
210
211/**************************************************************************
212 * MMDRV_Aux_UnMap32ATo16 [internal]
213 */
214static MMDRV_MapType MMDRV_Aux_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
215{
216#if 0
217 case AUXDM_GETDEVCAPS:
218 lpCaps->wMid = ac16.wMid;
219 lpCaps->wPid = ac16.wPid;
220 lpCaps->vDriverVersion = ac16.vDriverVersion;
221 strcpy(lpCaps->szPname, ac16.szPname);
222 lpCaps->wTechnology = ac16.wTechnology;
223 lpCaps->dwSupport = ac16.dwSupport;
224#endif
225 return MMDRV_MAP_MSGERROR;
226}
227
228/**************************************************************************
229 * MMDRV_Aux_Callback [internal]
230 */
231static void CALLBACK MMDRV_Aux_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
232{
233 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
234
235 FIXME("NIY\n");
236 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
237}
238
239/* =================================
240 * M I X E R M A P P E R S
241 * ================================= */
242
243/**************************************************************************
244 * xMMDRV_Mixer_Map16To32A [internal]
245 */
246static MMDRV_MapType MMDRV_Mixer_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
247{
248 return MMDRV_MAP_MSGERROR;
249}
250
251/**************************************************************************
252 * MMDRV_Mixer_UnMap16To32A [internal]
253 */
254static MMDRV_MapType MMDRV_Mixer_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
255{
256#if 0
257 MIXERCAPSA micA;
258 UINT ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
259
260 if (ret == MMSYSERR_NOERROR) {
261 mixcaps->wMid = micA.wMid;
262 mixcaps->wPid = micA.wPid;
263 mixcaps->vDriverVersion = micA.vDriverVersion;
264 strcpy(mixcaps->szPname, micA.szPname);
265 mixcaps->fdwSupport = micA.fdwSupport;
266 mixcaps->cDestinations = micA.cDestinations;
267 }
268 return ret;
269#endif
270 return MMDRV_MAP_MSGERROR;
271}
272
273/**************************************************************************
274 * MMDRV_Mixer_Map32ATo16 [internal]
275 */
276static MMDRV_MapType MMDRV_Mixer_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
277{
278 return MMDRV_MAP_MSGERROR;
279}
280
281/**************************************************************************
282 * MMDRV_Mixer_UnMap32ATo16 [internal]
283 */
284static MMDRV_MapType MMDRV_Mixer_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
285{
286 return MMDRV_MAP_MSGERROR;
287}
288
289/**************************************************************************
290 * MMDRV_Mixer_Callback [internal]
291 */
292static void CALLBACK MMDRV_Mixer_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
293{
294 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
295
296 FIXME("NIY\n");
297 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
298}
299
300/* =================================
301 * M I D I I N M A P P E R S
302 * ================================= */
303
304/**************************************************************************
305 * MMDRV_MidiIn_Map16To32A [internal]
306 */
307static MMDRV_MapType MMDRV_MidiIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
308{
309 return MMDRV_MAP_MSGERROR;
310}
311
312/**************************************************************************
313 * MMDRV_MidiIn_UnMap16To32A [internal]
314 */
315static MMDRV_MapType MMDRV_MidiIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
316{
317 return MMDRV_MAP_MSGERROR;
318}
319
320/**************************************************************************
321 * MMDRV_MidiIn_Map32ATo16 [internal]
322 */
323static MMDRV_MapType MMDRV_MidiIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
324{
325 return MMDRV_MAP_MSGERROR;
326}
327
328/**************************************************************************
329 * MMDRV_MidiIn_UnMap32ATo16 [internal]
330 */
331static MMDRV_MapType MMDRV_MidiIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
332{
333 return MMDRV_MAP_MSGERROR;
334}
335
336/**************************************************************************
337 * MMDRV_MidiIn_Callback [internal]
338 */
339static void CALLBACK MMDRV_MidiIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
340{
341 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
342
343 FIXME("NIY\n");
344 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
345}
346
347/* =================================
348 * M I D I O U T M A P P E R S
349 * ================================= */
350
351/**************************************************************************
352 * MMDRV_MidiOut_Map16To32A [internal]
353 */
354static MMDRV_MapType MMDRV_MidiOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
355{
356 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
357
358 switch (wMsg) {
359 case MODM_GETNUMDEVS:
360 case MODM_DATA:
361 case MODM_RESET:
362 case MODM_SETVOLUME:
363 ret = MMDRV_MAP_OK;
364 break;
365
366 case MODM_OPEN:
367 case MODM_CLOSE:
368 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
369 break;
370
371 case MODM_GETDEVCAPS:
372 {
373 LPMIDIOUTCAPSA moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSA));
374 LPMIDIOUTCAPS16 moc16 = PTR_SEG_TO_LIN(*lpParam1);
375
376 if (moc32) {
377 *(LPMIDIOUTCAPS16*)moc32 = moc16;
378 moc32 = (LPMIDIOUTCAPSA)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
379 *lpParam1 = (DWORD)moc32;
380 *lpParam2 = sizeof(MIDIOUTCAPSA);
381
382 ret = MMDRV_MAP_OKMEM;
383 } else {
384 ret = MMDRV_MAP_NOMEM;
385 }
386 }
387 break;
388 case MODM_PREPARE:
389 case MODM_UNPREPARE:
390 case MODM_LONGDATA:
391 case MODM_GETVOLUME:
392 case MODM_CACHEPATCHES:
393 case MODM_CACHEDRUMPATCHES:
394 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000395 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000396 break;
397 }
398 return ret;
399}
400
401/**************************************************************************
402 * MMDRV_MidiOut_UnMap16To32A [internal]
403 */
404static MMDRV_MapType MMDRV_MidiOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
405{
406 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
407
408 switch (wMsg) {
409 case MODM_GETNUMDEVS:
410 case MODM_DATA:
411 case MODM_RESET:
412 case MODM_SETVOLUME:
413 ret = MMDRV_MAP_OK;
414 break;
415
416 case MODM_OPEN:
417 case MODM_CLOSE:
418 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
419 break;
420
421 case MODM_GETDEVCAPS:
422 {
423 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)(*lpParam1);
424 LPMIDIOUTCAPS16 moc16 = *(LPMIDIOUTCAPS16*)((LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
425
426 moc16->wMid = moc32->wMid;
427 moc16->wPid = moc32->wPid;
428 moc16->vDriverVersion = moc32->vDriverVersion;
429 strcpy(moc16->szPname, moc32->szPname);
430 moc16->wTechnology = moc32->wTechnology;
431 moc16->wVoices = moc32->wVoices;
432 moc16->wNotes = moc32->wNotes;
433 moc16->wChannelMask = moc32->wChannelMask;
434 moc16->dwSupport = moc32->dwSupport;
435 HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
436 ret = MMDRV_MAP_OK;
437 }
438 break;
439 case MODM_PREPARE:
440 case MODM_UNPREPARE:
441 case MODM_LONGDATA:
442 case MODM_GETVOLUME:
443 case MODM_CACHEPATCHES:
444 case MODM_CACHEDRUMPATCHES:
445 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000446 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000447 break;
448 }
449 return ret;
450}
451
452/**************************************************************************
453 * MMDRV_MidiOut_Map32ATo16 [internal]
454 */
455static MMDRV_MapType MMDRV_MidiOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
456{
457 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
458
459 switch (wMsg) {
460 case MODM_CLOSE:
461 case MODM_GETNUMDEVS:
462 case MODM_DATA:
463 case MODM_RESET:
464 case MODM_SETVOLUME:
465 ret = MMDRV_MAP_OK;
466 break;
467 case MODM_GETDEVCAPS:
468 {
469 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)*lpParam1;
470 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPMIDIOUTCAPSA) + sizeof(MIDIOUTCAPS16));
471
472 if (ptr) {
473 *(LPMIDIOUTCAPSA*)ptr = moc32;
474 ret = MMDRV_MAP_OKMEM;
475 } else {
476 ret = MMDRV_MAP_NOMEM;
477 }
478 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIOUTCAPSA);
479 *lpParam2 = sizeof(MIDIOUTCAPS16);
480 }
481 break;
482 case MODM_OPEN:
483 case MODM_PREPARE:
484 case MODM_UNPREPARE:
485 case MODM_LONGDATA:
486 case MODM_GETVOLUME:
487 case MODM_CACHEPATCHES:
488 case MODM_CACHEDRUMPATCHES:
489 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000490 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000491 break;
492 }
493 return ret;
494}
495
496/**************************************************************************
497 * MMDRV_MidiOut_UnMap32ATo16 [internal]
498 */
499static MMDRV_MapType MMDRV_MidiOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
500{
501 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
502
503 switch (wMsg) {
504 case MODM_CLOSE:
505 case MODM_GETNUMDEVS:
506 case MODM_DATA:
507 case MODM_RESET:
508 case MODM_SETVOLUME:
509 ret = MMDRV_MAP_OK;
510 break;
511 case MODM_GETDEVCAPS:
512 {
513 LPMIDIOUTCAPS16 moc16 = (LPMIDIOUTCAPS16)PTR_SEG_TO_LIN(*lpParam1);
514 LPSTR ptr = (LPSTR)moc16 - sizeof(LPMIDIOUTCAPSA);
515 LPMIDIOUTCAPSA moc32 = *(LPMIDIOUTCAPSA*)ptr;
516
517 moc32->wMid = moc16->wMid;
518 moc32->wPid = moc16->wPid;
519 moc32->vDriverVersion = moc16->vDriverVersion;
520 strcpy(moc32->szPname, moc16->szPname);
521 moc32->wTechnology = moc16->wTechnology;
522 moc32->wVoices = moc16->wVoices;
523 moc32->wNotes = moc16->wNotes;
524 moc32->wChannelMask = moc16->wChannelMask;
525 moc32->dwSupport = moc16->dwSupport;
526
527 if (!SEGPTR_FREE(ptr))
528 FIXME("bad free line=%d\n", __LINE__);
529 ret = MMDRV_MAP_OK;
530 }
531 break;
532 case MODM_OPEN:
533 case MODM_PREPARE:
534 case MODM_UNPREPARE:
535 case MODM_LONGDATA:
536 case MODM_GETVOLUME:
537 case MODM_CACHEPATCHES:
538 case MODM_CACHEDRUMPATCHES:
539 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000540 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000541 break;
542 }
543 return ret;
544}
545
546/**************************************************************************
547 * MMDRV_MidiOut_Callback [internal]
548 */
549static void CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
550{
551 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
552
553 switch (uMsg) {
554 case MOM_OPEN:
555 case MOM_CLOSE:
556 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
557 break;
558 case MOM_DONE:
559 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
560 /* initial map is: 32 => 16 */
561 LPMIDIHDR wh16 = (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1);
562 LPMIDIHDR wh32 = *(LPMIDIHDR*)((LPSTR)wh16 - sizeof(LPMIDIHDR));
563
564 dwParam1 = (DWORD)wh32;
565 wh32->dwFlags = wh16->dwFlags;
566 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
567 /* initial map is: 16 => 32 */
568 LPMIDIHDR wh32 = (LPMIDIHDR)(dwParam1);
569 LPMIDIHDR segwh16 = *(LPMIDIHDR*)((LPSTR)wh32 - sizeof(LPMIDIHDR));
570 LPMIDIHDR wh16 = PTR_SEG_TO_LIN(segwh16);
571
572 dwParam1 = (DWORD)segwh16;
573 wh16->dwFlags = wh32->dwFlags;
574 }
575 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
576 break;
577 /* case MOM_POSITIONCB: */
578 default:
579 ERR("Unknown msg %u\n", uMsg);
580 }
581
582 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
583}
584
585/* =================================
586 * W A V E I N M A P P E R S
587 * ================================= */
588
589/**************************************************************************
590 * MMDRV_WaveIn_Map16To32A [internal]
591 */
592static MMDRV_MapType MMDRV_WaveIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
593{
594 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
595
596 switch (wMsg) {
597 case WIDM_GETNUMDEVS:
598 case WIDM_RESET:
599 case WIDM_START:
600 case WIDM_STOP:
601 ret = MMDRV_MAP_OK;
602 break;
603 case WIDM_OPEN:
604 case WIDM_CLOSE:
605 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
606 break;
607 case WIDM_GETDEVCAPS:
608 {
609 LPWAVEINCAPSA wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSA));
610 LPWAVEINCAPS16 wic16 = PTR_SEG_TO_LIN(*lpParam1);
611
612 if (wic32) {
613 *(LPWAVEINCAPS16*)wic32 = wic16;
614 wic32 = (LPWAVEINCAPSA)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
615 *lpParam1 = (DWORD)wic32;
616 *lpParam2 = sizeof(WAVEINCAPSA);
617
618 ret = MMDRV_MAP_OKMEM;
619 } else {
620 ret = MMDRV_MAP_NOMEM;
621 }
622 }
623 break;
624 case WIDM_GETPOS:
625 {
626 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
627 LPMMTIME16 mmt16 = PTR_SEG_TO_LIN(*lpParam1);
628
629 if (mmt32) {
630 *(LPMMTIME16*)mmt32 = mmt16;
631 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
632
633 mmt32->wType = mmt16->wType;
634 *lpParam1 = (DWORD)mmt32;
635 *lpParam2 = sizeof(MMTIME);
636
637 ret = MMDRV_MAP_OKMEM;
638 } else {
639 ret = MMDRV_MAP_NOMEM;
640 }
641 }
642 break;
643 case WIDM_PREPARE:
644 {
645 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
646 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
647
648 if (wh32) {
649 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
650 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
651 wh32->lpData = PTR_SEG_TO_LIN(wh16->lpData);
652 wh32->dwBufferLength = wh16->dwBufferLength;
653 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
654 wh32->dwUser = wh16->dwUser;
655 wh32->dwFlags = wh16->dwFlags;
656 wh32->dwLoops = wh16->dwLoops;
657 /* FIXME: nothing on wh32->lpNext */
658 /* could link the wh32->lpNext at this level for memory house keeping */
659 wh16->lpNext = wh32; /* for reuse in unprepare and write */
Eric Pouech4853b6d1999-09-22 16:52:47 +0000660 *lpParam1 = (DWORD)wh32;
661 *lpParam2 = sizeof(WAVEHDR);
662
663 ret = MMDRV_MAP_OKMEM;
664 } else {
665 ret = MMDRV_MAP_NOMEM;
666 }
667 }
668 break;
669 case WIDM_ADDBUFFER:
670 case WIDM_UNPREPARE:
671 {
672 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
673 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
674
675 *lpParam1 = (DWORD)wh32;
676 *lpParam2 = sizeof(WAVEHDR);
677 ret = MMDRV_MAP_OKMEM;
678 }
679 break;
680 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000681 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
682 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000683 break;
684 }
685 return ret;
686}
687
688/**************************************************************************
689 * MMDRV_WaveIn_UnMap16To32A [internal]
690 */
691static MMDRV_MapType MMDRV_WaveIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
692{
693 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
694
695 switch (wMsg) {
696 case WIDM_GETNUMDEVS:
697 case WIDM_RESET:
698 case WIDM_START:
699 case WIDM_STOP:
700 ret = MMDRV_MAP_OK;
701 break;
702 case WIDM_OPEN:
703 case WIDM_CLOSE:
704 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
705 break;
706 case WIDM_GETDEVCAPS:
707 {
708 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)(*lpParam1);
709 LPWAVEINCAPS16 wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
710
711 wic16->wMid = wic32->wMid;
712 wic16->wPid = wic32->wPid;
713 wic16->vDriverVersion = wic32->vDriverVersion;
714 strcpy(wic16->szPname, wic32->szPname);
715 wic16->dwFormats = wic32->dwFormats;
716 wic16->wChannels = wic32->wChannels;
717 HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
718 ret = MMDRV_MAP_OK;
719 }
720 break;
721 case WIDM_GETPOS:
722 {
723 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
724 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
725
726 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
727 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
728 ret = MMDRV_MAP_OK;
729 }
730 break;
731 case WIDM_ADDBUFFER:
732 case WIDM_PREPARE:
733 case WIDM_UNPREPARE:
734 {
735 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
736 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
737
738 assert(wh16->lpNext == wh32);
739 wh16->dwBufferLength = wh32->dwBufferLength;
740 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
741 wh16->dwUser = wh32->dwUser;
742 wh16->dwFlags = wh32->dwFlags;
743 wh16->dwLoops = wh32->dwLoops;
744
745 if (wMsg == WIDM_UNPREPARE) {
746 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
747 wh16->lpNext = 0;
748 }
749 ret = MMDRV_MAP_OK;
750 }
751 break;
752 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000753 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000754 break;
755 }
756 return ret;
757}
758
759/**************************************************************************
760 * MMDRV_WaveIn_Map32ATo16 [internal]
761 */
762static MMDRV_MapType MMDRV_WaveIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
763{
764 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
765
766 switch (wMsg) {
767 case WIDM_CLOSE:
768 case WIDM_GETNUMDEVS:
769 case WIDM_RESET:
770 case WIDM_START:
771 case WIDM_STOP:
772 ret = MMDRV_MAP_OK;
773 break;
774
775 case WIDM_OPEN:
776 {
777 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
778 int sz = sizeof(WAVEFORMATEX);
779 LPVOID ptr;
780 LPWAVEOPENDESC16 wod16;
781
782 /* allocated data are mapped as follows:
783 LPWAVEOPENDESC ptr to orig lParam1
784 DWORD ptr to orig dwUser, which is a pointer to DWORD:driver dwInstance
785 DWORD dwUser passed to driver
786 WAVEOPENDESC16 wod16: openDesc passed to driver
787 WAVEFORMATEX openDesc->lpFormat passed to driver
788 xxx extra bytes to WAVEFORMATEX
789 */
790 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
791 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
792 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
793 }
794
795 ptr = SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
796
797 if (ptr) {
798 *(LPWAVEOPENDESC*)ptr = wod32;
799 *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
800 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
801
802 wod16->hWave = wod32->hWave;
803 wod16->lpFormat = (LPWAVEFORMATEX)((DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
804 memcpy(wod16 + 1, wod32->lpFormat, sz);
805
806 wod16->dwCallback = wod32->dwCallback;
807 wod16->dwInstance = wod32->dwInstance;
808 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
809 wod16->dnDevNode = wod32->dnDevNode;
810
811 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
812 *lpdwUser = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
813
814 ret = MMDRV_MAP_OKMEM;
815 } else {
816 ret = MMDRV_MAP_NOMEM;
817 }
818 }
819 break;
820 case WIDM_PREPARE:
821 {
822 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
823 LPWAVEHDR wh16;
824 LPVOID ptr = SEGPTR_ALLOC(sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
825
826 if (ptr) {
827 *(LPWAVEHDR*)ptr = wh32;
828 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
829 wh16->lpData = (LPSTR)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
830 /* data will be copied on WODM_WRITE */
831 wh16->dwBufferLength = wh32->dwBufferLength;
832 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
833 wh16->dwUser = wh32->dwUser;
834 wh16->dwFlags = wh32->dwFlags;
835 wh16->dwLoops = wh32->dwLoops;
836 /* FIXME: nothing on wh32->lpNext */
837 /* could link the wh32->lpNext at this level for memory house keeping */
838 wh32->lpNext = wh16; /* for reuse in unprepare and write */
Eric Pouech4853b6d1999-09-22 16:52:47 +0000839 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
840 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
841 wh32->dwBufferLength, (DWORD)wh32->lpData);
842 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
843 *lpParam2 = sizeof(WAVEHDR);
844
845 ret = MMDRV_MAP_OKMEM;
846 } else {
847 ret = MMDRV_MAP_NOMEM;
848 }
849 }
850 break;
851 case WIDM_ADDBUFFER:
852 case WIDM_UNPREPARE:
853 {
854 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
855 LPWAVEHDR wh16 = wh32->lpNext;
856 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
857
858 assert(*(LPWAVEHDR*)ptr == wh32);
859
860 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
861 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
862 wh32->dwBufferLength, (DWORD)wh32->lpData);
863
864 if (wMsg == WODM_WRITE)
865 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
866
867 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
868 *lpParam2 = sizeof(WAVEHDR);
869 ret = MMDRV_MAP_OKMEM;
870 }
871 break;
872 case WIDM_GETDEVCAPS:
873 {
874 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)*lpParam1;
875 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPWAVEINCAPSA) + sizeof(WAVEINCAPS16));
876
877 if (ptr) {
878 *(LPWAVEINCAPSA*)ptr = wic32;
879 ret = MMDRV_MAP_OKMEM;
880 } else {
881 ret = MMDRV_MAP_NOMEM;
882 }
883 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEINCAPSA);
884 *lpParam2 = sizeof(WAVEINCAPS16);
885 }
886 break;
887 case WIDM_GETPOS:
888 {
889 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
890 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPMMTIME) + sizeof(MMTIME16));
891 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
892
893 if (ptr) {
894 *(LPMMTIME*)ptr = mmt32;
895 mmt16->wType = mmt32->wType;
896 ret = MMDRV_MAP_OKMEM;
897 } else {
898 ret = MMDRV_MAP_NOMEM;
899 }
900 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMMTIME);
901 *lpParam2 = sizeof(MMTIME16);
902 }
903 break;
904 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000905 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000906 break;
907 }
908 return ret;
909}
910
911/**************************************************************************
912 * MMDRV_WaveIn_UnMap32ATo16 [internal]
913 */
914static MMDRV_MapType MMDRV_WaveIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
915{
916 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
917
918 switch (wMsg) {
919 case WIDM_CLOSE:
920 case WIDM_GETNUMDEVS:
921 case WIDM_RESET:
922 case WIDM_START:
923 case WIDM_STOP:
924 ret = MMDRV_MAP_OK;
925 break;
926
927 case WIDM_OPEN:
928 {
929 LPWAVEOPENDESC16 wod16 = (LPWAVEOPENDESC16)PTR_SEG_TO_LIN(*lpParam1);
930 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
931 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
932
933 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
934 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
935
936 if (!SEGPTR_FREE(ptr))
937 FIXME("bad free line=%d\n", __LINE__);
938
939 ret = MMDRV_MAP_OK;
940 }
941 break;
942
943 case WIDM_ADDBUFFER:
944 case WIDM_PREPARE:
945 case WIDM_UNPREPARE:
946 {
947 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(*lpParam1);
948 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
949 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
950
951 assert(wh32->lpNext == wh16);
952 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
953 wh32->dwUser = wh16->dwUser;
954 wh32->dwFlags = wh16->dwFlags;
955 wh32->dwLoops = wh16->dwLoops;
956
957 if (wMsg == WODM_UNPREPARE) {
958 if (!SEGPTR_FREE(ptr))
959 FIXME("bad free line=%d\n", __LINE__);
960 wh32->lpNext = 0;
961 }
962 ret = MMDRV_MAP_OK;
963 }
964 break;
965 case WIDM_GETDEVCAPS:
966 {
967 LPWAVEINCAPS16 wic16 = (LPWAVEINCAPS16)PTR_SEG_TO_LIN(*lpParam1);
968 LPSTR ptr = (LPSTR)wic16 - sizeof(LPWAVEINCAPSA);
969 LPWAVEINCAPSA wic32 = *(LPWAVEINCAPSA*)ptr;
970
971 wic32->wMid = wic16->wMid;
972 wic32->wPid = wic16->wPid;
973 wic32->vDriverVersion = wic16->vDriverVersion;
974 strcpy(wic32->szPname, wic16->szPname);
975 wic32->dwFormats = wic16->dwFormats;
976 wic32->wChannels = wic16->wChannels;
977 if (!SEGPTR_FREE(ptr))
978 FIXME("bad free line=%d\n", __LINE__);
979 ret = MMDRV_MAP_OK;
980 }
981 break;
982 case WIDM_GETPOS:
983 {
984 LPMMTIME16 mmt16 = (LPMMTIME16)PTR_SEG_TO_LIN(*lpParam1);
985 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
986 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
987
988 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
989
990 if (!SEGPTR_FREE(ptr))
991 FIXME("bad free line=%d\n", __LINE__);
992
993 ret = MMDRV_MAP_OK;
994 }
995 break;
996 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000997 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000998 break;
999 }
1000 return ret;
1001}
1002
1003/**************************************************************************
1004 * MMDRV_WaveIn_Callback [internal]
1005 */
1006static void CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1007{
1008 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1009
1010 switch (uMsg) {
1011 case WIM_OPEN:
1012 case WIM_CLOSE:
1013 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1014 break;
1015 case WIM_DATA:
1016 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1017 /* initial map is: 32 => 16 */
1018 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1);
1019 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1020
1021 dwParam1 = (DWORD)wh32;
1022 wh32->dwFlags = wh16->dwFlags;
1023 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1024 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1025 /* initial map is: 16 => 32 */
1026 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1027 LPWAVEHDR segwh16 = *(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1028 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(segwh16);
1029
1030 dwParam1 = (DWORD)segwh16;
1031 wh16->dwFlags = wh32->dwFlags;
1032 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1033 }
1034 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1035 break;
1036 default:
1037 ERR("Unknown msg %u\n", uMsg);
1038 }
1039
1040 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1041}
1042
1043/* =================================
1044 * W A V E O U T M A P P E R S
1045 * ================================= */
1046
1047/**************************************************************************
1048 * MMDRV_WaveOut_Map16To32A [internal]
1049 */
1050static MMDRV_MapType MMDRV_WaveOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1051{
1052 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1053
1054 switch (wMsg) {
1055 /* nothing to do */
1056 case WODM_BREAKLOOP:
1057 case WODM_CLOSE:
1058 case WODM_GETNUMDEVS:
1059 case WODM_PAUSE:
1060 case WODM_RESET:
1061 case WODM_RESTART:
1062 case WODM_SETPITCH:
1063 case WODM_SETPLAYBACKRATE:
1064 case WODM_SETVOLUME:
1065 ret = MMDRV_MAP_OK;
1066 break;
1067
1068 case WODM_GETPITCH:
1069 case WODM_GETPLAYBACKRATE:
1070 case WODM_GETVOLUME:
1071 case WODM_OPEN:
1072 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1073 break;
1074
1075 case WODM_GETDEVCAPS:
1076 {
1077 LPWAVEOUTCAPSA woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSA));
1078 LPWAVEOUTCAPS16 woc16 = PTR_SEG_TO_LIN(*lpParam1);
1079
1080 if (woc32) {
1081 *(LPWAVEOUTCAPS16*)woc32 = woc16;
1082 woc32 = (LPWAVEOUTCAPSA)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
1083 *lpParam1 = (DWORD)woc32;
1084 *lpParam2 = sizeof(WAVEOUTCAPSA);
1085
1086 ret = MMDRV_MAP_OKMEM;
1087 } else {
1088 ret = MMDRV_MAP_NOMEM;
1089 }
1090 }
1091 break;
1092 case WODM_GETPOS:
1093 {
1094 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
1095 LPMMTIME16 mmt16 = PTR_SEG_TO_LIN(*lpParam1);
1096
1097 if (mmt32) {
1098 *(LPMMTIME16*)mmt32 = mmt16;
1099 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
1100
1101 mmt32->wType = mmt16->wType;
1102 *lpParam1 = (DWORD)mmt32;
1103 *lpParam2 = sizeof(MMTIME);
1104
1105 ret = MMDRV_MAP_OKMEM;
1106 } else {
1107 ret = MMDRV_MAP_NOMEM;
1108 }
1109 }
1110 break;
1111 case WODM_PREPARE:
1112 {
1113 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
1114 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
1115
1116 if (wh32) {
1117 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
1118 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
1119 wh32->lpData = PTR_SEG_TO_LIN(wh16->lpData);
1120 wh32->dwBufferLength = wh16->dwBufferLength;
1121 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1122 wh32->dwUser = wh16->dwUser;
1123 wh32->dwFlags = wh16->dwFlags;
1124 wh32->dwLoops = wh16->dwLoops;
1125 /* FIXME: nothing on wh32->lpNext */
1126 /* could link the wh32->lpNext at this level for memory house keeping */
1127 wh16->lpNext = wh32; /* for reuse in unprepare and write */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001128 *lpParam1 = (DWORD)wh32;
1129 *lpParam2 = sizeof(WAVEHDR);
1130
1131 ret = MMDRV_MAP_OKMEM;
1132 } else {
1133 ret = MMDRV_MAP_NOMEM;
1134 }
1135 }
1136 break;
1137 case WODM_UNPREPARE:
1138 case WODM_WRITE:
1139 {
1140 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
1141 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
1142
1143 *lpParam1 = (DWORD)wh32;
1144 *lpParam2 = sizeof(WAVEHDR);
1145 ret = MMDRV_MAP_OKMEM;
1146 }
1147 break;
1148 default:
Eric Pouech31a19331999-11-21 00:51:05 +00001149 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +00001150 break;
1151 }
1152 return ret;
1153}
1154
1155/**************************************************************************
1156 * MMDRV_WaveOut_UnMap16To32A [internal]
1157 */
1158static MMDRV_MapType MMDRV_WaveOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1159{
1160 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1161
1162 switch (wMsg) {
1163 /* nothing to do */
1164 case WODM_BREAKLOOP:
1165 case WODM_CLOSE:
1166 case WODM_GETNUMDEVS:
1167 case WODM_PAUSE:
1168 case WODM_RESET:
1169 case WODM_RESTART:
1170 case WODM_SETPITCH:
1171 case WODM_SETPLAYBACKRATE:
1172 case WODM_SETVOLUME:
1173 ret = MMDRV_MAP_OK;
1174 break;
1175
1176 case WODM_GETPITCH:
1177 case WODM_GETPLAYBACKRATE:
1178 case WODM_GETVOLUME:
1179 case WODM_OPEN:
1180 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1181 break;
1182
1183 case WODM_GETDEVCAPS:
1184 {
1185 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)(*lpParam1);
1186 LPWAVEOUTCAPS16 woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1187
1188 woc16->wMid = woc32->wMid;
1189 woc16->wPid = woc32->wPid;
1190 woc16->vDriverVersion = woc32->vDriverVersion;
1191 strcpy(woc16->szPname, woc32->szPname);
1192 woc16->dwFormats = woc32->dwFormats;
1193 woc16->wChannels = woc32->wChannels;
1194 woc16->dwSupport = woc32->dwSupport;
1195 HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1196 ret = MMDRV_MAP_OK;
1197 }
1198 break;
1199 case WODM_GETPOS:
1200 {
1201 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
1202 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
1203
1204 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
1205 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1206 ret = MMDRV_MAP_OK;
1207 }
1208 break;
1209 case WODM_PREPARE:
1210 case WODM_UNPREPARE:
1211 case WODM_WRITE:
1212 {
1213 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1214 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1215
1216 assert(wh16->lpNext == wh32);
1217 wh16->dwBufferLength = wh32->dwBufferLength;
1218 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1219 wh16->dwUser = wh32->dwUser;
1220 wh16->dwFlags = wh32->dwFlags;
1221 wh16->dwLoops = wh32->dwLoops;
1222
1223 if (wMsg == WODM_UNPREPARE) {
1224 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1225 wh16->lpNext = 0;
1226 }
1227 ret = MMDRV_MAP_OK;
1228 }
1229 break;
1230 default:
Eric Pouech31a19331999-11-21 00:51:05 +00001231 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +00001232 break;
1233 }
1234 return ret;
1235}
1236
1237/**************************************************************************
1238 * MMDRV_WaveOut_Map32ATo16 [internal]
1239 */
1240static MMDRV_MapType MMDRV_WaveOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1241{
1242 MMDRV_MapType ret;
1243
1244 switch (wMsg) {
1245 /* nothing to do */
1246 case WODM_BREAKLOOP:
1247 case WODM_CLOSE:
1248 case WODM_GETNUMDEVS:
1249 case WODM_PAUSE:
1250 case WODM_RESET:
1251 case WODM_RESTART:
1252 case WODM_SETPITCH:
1253 case WODM_SETPLAYBACKRATE:
1254 case WODM_SETVOLUME:
1255 ret = MMDRV_MAP_OK;
1256 break;
1257
1258 case WODM_GETDEVCAPS:
1259 {
1260 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)*lpParam1;
1261 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPWAVEOUTCAPSA) + sizeof(WAVEOUTCAPS16));
1262
1263 if (ptr) {
1264 *(LPWAVEOUTCAPSA*)ptr = woc32;
1265 ret = MMDRV_MAP_OKMEM;
1266 } else {
1267 ret = MMDRV_MAP_NOMEM;
1268 }
1269 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOUTCAPSA);
1270 *lpParam2 = sizeof(WAVEOUTCAPS16);
1271 }
1272 break;
1273 case WODM_GETPITCH:
1274 FIXME("NIY: no conversion yet\n");
1275 ret = MMDRV_MAP_MSGERROR;
1276 break;
1277 case WODM_GETPLAYBACKRATE:
1278 FIXME("NIY: no conversion yet\n");
1279 ret = MMDRV_MAP_MSGERROR;
1280 break;
1281 case WODM_GETPOS:
1282 {
1283 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1284 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPMMTIME) + sizeof(MMTIME16));
1285 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1286
1287 if (ptr) {
1288 *(LPMMTIME*)ptr = mmt32;
1289 mmt16->wType = mmt32->wType;
1290 ret = MMDRV_MAP_OKMEM;
1291 } else {
1292 ret = MMDRV_MAP_NOMEM;
1293 }
1294 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMMTIME);
1295 *lpParam2 = sizeof(MMTIME16);
1296 }
1297 break;
1298 case WODM_GETVOLUME:
1299 FIXME("NIY: no conversion yet\n");
1300 ret = MMDRV_MAP_MSGERROR;
1301 break;
1302 case WODM_OPEN:
1303 {
1304 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1305 int sz = sizeof(WAVEFORMATEX);
1306 LPVOID ptr;
1307 LPWAVEOPENDESC16 wod16;
1308
1309 /* allocated data are mapped as follows:
1310 LPWAVEOPENDESC ptr to orig lParam1
1311 DWORD ptr to orig dwUser, which is a pointer to DWORD:driver dwInstance
1312 DWORD dwUser passed to driver
1313 WAVEOPENDESC16 wod16: openDesc passed to driver
1314 WAVEFORMATEX openDesc->lpFormat passed to driver
1315 xxx extra bytes to WAVEFORMATEX
1316 */
1317 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1318 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1319 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1320 }
1321
1322 ptr = SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1323
1324 if (ptr) {
1325 *(LPWAVEOPENDESC*)ptr = wod32;
1326 *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1327 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1328
1329 wod16->hWave = wod32->hWave;
1330 wod16->lpFormat = (LPWAVEFORMATEX)((DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1331 memcpy(wod16 + 1, wod32->lpFormat, sz);
1332
1333 wod16->dwCallback = wod32->dwCallback;
1334 wod16->dwInstance = wod32->dwInstance;
1335 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1336 wod16->dnDevNode = wod32->dnDevNode;
1337
1338 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1339 *lpdwUser = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1340
1341 ret = MMDRV_MAP_OKMEM;
1342 } else {
1343 ret = MMDRV_MAP_NOMEM;
1344 }
1345 }
1346 break;
1347 case WODM_PREPARE:
1348 {
1349 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1350 LPWAVEHDR wh16;
1351 LPVOID ptr = SEGPTR_ALLOC(sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1352
1353 if (ptr) {
1354 *(LPWAVEHDR*)ptr = wh32;
1355 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1356 wh16->lpData = (LPSTR)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1357 /* data will be copied on WODM_WRITE */
1358 wh16->dwBufferLength = wh32->dwBufferLength;
1359 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1360 wh16->dwUser = wh32->dwUser;
1361 wh16->dwFlags = wh32->dwFlags;
1362 wh16->dwLoops = wh32->dwLoops;
1363 /* FIXME: nothing on wh32->lpNext */
1364 /* could link the wh32->lpNext at this level for memory house keeping */
1365 wh32->lpNext = wh16; /* for reuse in unprepare and write */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001366 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1367 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1368 wh32->dwBufferLength, (DWORD)wh32->lpData);
1369 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
1370 *lpParam2 = sizeof(WAVEHDR);
1371
1372 ret = MMDRV_MAP_OKMEM;
1373 } else {
1374 ret = MMDRV_MAP_NOMEM;
1375 }
1376 }
1377 break;
1378 case WODM_UNPREPARE:
1379 case WODM_WRITE:
1380 {
1381 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1382 LPWAVEHDR wh16 = wh32->lpNext;
1383 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1384
1385 assert(*(LPWAVEHDR*)ptr == wh32);
1386
1387 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1388 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1389 wh32->dwBufferLength, (DWORD)wh32->lpData);
1390
1391 if (wMsg == WODM_WRITE)
1392 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1393
1394 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
1395 *lpParam2 = sizeof(WAVEHDR);
1396 ret = MMDRV_MAP_OKMEM;
1397 }
1398 break;
1399 default:
1400 FIXME("NIY: no conversion yet\n");
1401 ret = MMDRV_MAP_MSGERROR;
1402 break;
1403 }
1404 return ret;
1405}
1406
1407/**************************************************************************
1408 * MMDRV_WaveOut_UnMap32ATo16 [internal]
1409 */
1410static MMDRV_MapType MMDRV_WaveOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1411{
1412 MMDRV_MapType ret;
1413
1414 switch (wMsg) {
1415 /* nothing to do */
1416 case WODM_BREAKLOOP:
1417 case WODM_CLOSE:
1418 case WODM_GETNUMDEVS:
1419 case WODM_PAUSE:
1420 case WODM_RESET:
1421 case WODM_RESTART:
1422 case WODM_SETPITCH:
1423 case WODM_SETPLAYBACKRATE:
1424 case WODM_SETVOLUME:
1425 ret = MMDRV_MAP_OK;
1426 break;
1427
1428 case WODM_GETDEVCAPS:
1429 {
1430 LPWAVEOUTCAPS16 woc16 = (LPWAVEOUTCAPS16)PTR_SEG_TO_LIN(*lpParam1);
1431 LPSTR ptr = (LPSTR)woc16 - sizeof(LPWAVEOUTCAPSA);
1432 LPWAVEOUTCAPSA woc32 = *(LPWAVEOUTCAPSA*)ptr;
1433
1434 woc32->wMid = woc16->wMid;
1435 woc32->wPid = woc16->wPid;
1436 woc32->vDriverVersion = woc16->vDriverVersion;
1437 strcpy(woc32->szPname, woc16->szPname);
1438 woc32->dwFormats = woc16->dwFormats;
1439 woc32->wChannels = woc16->wChannels;
1440 woc32->dwSupport = woc16->dwSupport;
1441 if (!SEGPTR_FREE(ptr))
1442 FIXME("bad free line=%d\n", __LINE__);
1443 ret = MMDRV_MAP_OK;
1444 }
1445 break;
1446 case WODM_GETPITCH:
1447 FIXME("NIY: no conversion yet\n");
1448 ret = MMDRV_MAP_MSGERROR;
1449 break;
1450 case WODM_GETPLAYBACKRATE:
1451 FIXME("NIY: no conversion yet\n");
1452 ret = MMDRV_MAP_MSGERROR;
1453 break;
1454 case WODM_GETPOS:
1455 {
1456 LPMMTIME16 mmt16 = (LPMMTIME16)PTR_SEG_TO_LIN(*lpParam1);
1457 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1458 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1459
1460 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1461
1462 if (!SEGPTR_FREE(ptr))
1463 FIXME("bad free line=%d\n", __LINE__);
1464
1465 ret = MMDRV_MAP_OK;
1466 }
1467 break;
1468 case WODM_OPEN:
1469 {
1470 LPWAVEOPENDESC16 wod16 = (LPWAVEOPENDESC16)PTR_SEG_TO_LIN(*lpParam1);
1471 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1472 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1473
1474 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1475 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1476
1477 if (!SEGPTR_FREE(ptr))
1478 FIXME("bad free line=%d\n", __LINE__);
1479
1480 ret = MMDRV_MAP_OK;
1481 }
1482 break;
1483 case WODM_PREPARE:
1484 case WODM_UNPREPARE:
1485 case WODM_WRITE:
1486 {
1487 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(*lpParam1);
1488 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1489 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1490
1491 assert(wh32->lpNext == wh16);
1492 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1493 wh32->dwUser = wh16->dwUser;
1494 wh32->dwFlags = wh16->dwFlags;
1495 wh32->dwLoops = wh16->dwLoops;
1496
1497 if (wMsg == WODM_UNPREPARE) {
1498 if (!SEGPTR_FREE(ptr))
1499 FIXME("bad free line=%d\n", __LINE__);
1500 wh32->lpNext = 0;
1501 }
1502 ret = MMDRV_MAP_OK;
1503 }
1504 break;
1505 case WODM_GETVOLUME:
1506 FIXME("NIY: no conversion yet\n");
1507 ret = MMDRV_MAP_MSGERROR;
1508 break;
1509 default:
1510 FIXME("NIY: no conversion yet\n");
1511 ret = MMDRV_MAP_MSGERROR;
1512 break;
1513 }
1514 return ret;
1515}
1516
1517/**************************************************************************
1518 * MMDRV_WaveOut_Callback [internal]
1519 */
1520static void CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1521{
1522 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1523
1524 switch (uMsg) {
1525 case WOM_OPEN:
1526 case WOM_CLOSE:
1527 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1528 break;
1529 case WOM_DONE:
1530 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1531 /* initial map is: 32 => 16 */
1532 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1);
1533 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1534
1535 dwParam1 = (DWORD)wh32;
1536 wh32->dwFlags = wh16->dwFlags;
1537 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1538 /* initial map is: 16 => 32 */
1539 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1540 LPWAVEHDR segwh16 = *(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1541 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(segwh16);
1542
1543 dwParam1 = (DWORD)segwh16;
1544 wh16->dwFlags = wh32->dwFlags;
1545 }
1546 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1547 break;
1548 default:
1549 ERR("Unknown msg %u\n", uMsg);
1550 }
1551
1552 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1553}
1554
1555#define A(_x,_y) {#_y, _x, \
1556MMDRV_##_y##_Map16To32A, MMDRV_##_y##_UnMap16To32A, \
1557MMDRV_##_y##_Map32ATo16, MMDRV_##_y##_UnMap32ATo16, \
1558MMDRV_##_y##_Callback, 0, NULL, -1}
1559
1560/* Note: the indices of this array must match the definitions
1561 * of the MMDRV_???? manifest constants
1562 */
1563static WINE_LLTYPE llTypes[MMDRV_MAX] = {
1564 A(TRUE, Aux),
1565 A(FALSE, Mixer),
1566 A(TRUE, MidiIn),
1567 A(TRUE, MidiOut),
1568 A(TRUE, WaveIn),
1569 A(TRUE, WaveOut),
1570};
1571#undef A
1572
1573/**************************************************************************
1574 * MMDRV_GetNum [internal]
1575 */
1576UINT MMDRV_GetNum(UINT type)
1577{
1578 assert(type < MMDRV_MAX);
1579 return llTypes[type].wMaxId;
1580}
1581
1582/**************************************************************************
1583 * WINE_Message [internal]
1584 */
1585DWORD MMDRV_Message(LPWINE_MLD mld, WORD wMsg, DWORD dwParam1,
1586 DWORD dwParam2, BOOL bFrom32)
1587{
1588 LPWINE_MM_DRIVER lpDrv;
1589 DWORD ret;
1590 WINE_MM_DRIVER_PART* part;
1591 WINE_LLTYPE* llType = &llTypes[mld->type];
1592 MMDRV_MapType map;
1593 int devID;
1594
1595 TRACE("(%s %u %u 0x%08lx 0x%08lx 0x%08lx %c)!\n",
1596 llTypes[mld->type].name, mld->uDeviceID, wMsg,
1597 mld->dwDriverInstance, dwParam1, dwParam2, bFrom32?'Y':'N');
1598
1599 if (mld->uDeviceID == (UINT16)-1) {
1600 if (!llType->bSupportMapper) {
1601 WARN("uDev=-1 requested on non-mappable ll type %s\n",
1602 llTypes[mld->type].name);
1603 return MMSYSERR_BADDEVICEID;
1604 }
1605 devID = -1;
1606 } else {
1607 if (mld->uDeviceID >= llType->wMaxId) {
1608 WARN("uDev(%u) requested >= max (%d)\n", mld->uDeviceID, llType->wMaxId);
1609 return MMSYSERR_BADDEVICEID;
1610 }
1611 devID = mld->uDeviceID;
1612 }
1613
1614 lpDrv = &MMDrvs[mld->mmdIndex];
1615 part = &lpDrv->parts[mld->type];
1616
1617#if 0
1618 /* some sanity checks */
1619 if (!(part->nIDMin <= devID))
1620 ERR("!(part->nIDMin(%d) <= devID(%d))\n", part->nIDMin, devID);
1621 if (!(devID < part->nIDMax))
1622 ERR("!(devID(%d) < part->nIDMax(%d))\n", devID, part->nIDMax);
1623#endif
1624
1625 if (lpDrv->bIs32) {
1626 assert(part->u.fnMessage32);
1627
1628 if (bFrom32) {
1629 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1630 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1631 ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1632 TRACE("=> %lu\n", ret);
1633 } else {
1634 map = llType->Map16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1635 switch (map) {
1636 case MMDRV_MAP_NOMEM:
1637 ret = MMSYSERR_NOMEM;
1638 break;
1639 case MMDRV_MAP_MSGERROR:
1640 FIXME("NIY: no conversion yet 16->32 (%u)\n", wMsg);
1641 ret = MMSYSERR_ERROR;
1642 break;
1643 case MMDRV_MAP_OK:
1644 case MMDRV_MAP_OKMEM:
1645 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1646 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1647 ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance,
1648 dwParam1, dwParam2);
1649 TRACE("=> %lu\n", ret);
1650 if (map == MMDRV_MAP_OKMEM)
1651 llType->UnMap16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1652 break;
1653 default:
1654 case MMDRV_MAP_PASS:
1655 FIXME("NIY: pass used ?\n");
1656 ret = MMSYSERR_NOTSUPPORTED;
1657 break;
1658 }
1659 }
1660 } else {
1661 assert(part->u.fnMessage16);
1662
1663 if (bFrom32) {
1664 map = llType->Map32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1665 switch (map) {
1666 case MMDRV_MAP_NOMEM:
1667 ret = MMSYSERR_NOMEM;
1668 break;
1669 case MMDRV_MAP_MSGERROR:
1670 FIXME("NIY: no conversion yet 32->16 (%u)\n", wMsg);
1671 ret = MMSYSERR_ERROR;
1672 break;
1673 case MMDRV_MAP_OK:
1674 case MMDRV_MAP_OKMEM:
1675 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1676 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1677 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
1678 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1679 TRACE("=> %lu\n", ret);
1680 if (map == MMDRV_MAP_OKMEM)
1681 llType->UnMap32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1682 break;
1683 default:
1684 case MMDRV_MAP_PASS:
1685 FIXME("NIY: pass used ?\n");
1686 ret = MMSYSERR_NOTSUPPORTED;
1687 break;
1688 }
1689 } else {
1690 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1691 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1692 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
1693 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1694 TRACE("=> %lu\n", ret);
1695 }
1696 }
1697 return ret;
1698}
1699
1700/**************************************************************************
1701 * MMDRV_Alloc [internal]
1702 */
1703LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
1704 DWORD* dwCallback, DWORD* dwInstance, BOOL bFrom32)
1705{
1706 LPWINE_MLD mld;
1707
1708 if ((*hndl = USER_HEAP_ALLOC(size)) == 0)
1709 return NULL;
1710
1711 mld = (LPWINE_MLD) USER_HEAP_LIN_ADDR(*hndl);
1712 if (!mld) return NULL;
1713 mld->type = type;
1714 if ((UINT)*hndl < MMDRV_GetNum(type) || HIWORD(*hndl) != 0) {
1715 /* FIXME: those conditions must be fulfilled so that:
1716 * - we can distinguish between device IDs and handles
1717 * - we can use handles as 16 or 32 bit entities
1718 */
1719 ERR("Shouldn't happen. Bad allocation scheme\n");
1720 }
1721
1722 mld->bFrom32 = bFrom32;
1723 mld->dwFlags = HIWORD(*dwFlags);
1724 mld->dwCallback = *dwCallback;
1725 mld->dwClientInstance = *dwInstance;
1726
1727 *dwFlags = LOWORD(*dwFlags) | CALLBACK_FUNCTION;
1728 *dwCallback = (DWORD)llTypes[type].Callback;
1729 *dwInstance = (DWORD)mld; /* FIXME: wouldn't some 16 bit drivers only use the loword ? */
1730
1731 return mld;
1732}
1733
1734/**************************************************************************
1735 * MMDRV_Free [internal]
1736 */
1737void MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
1738{
1739 USER_HEAP_FREE(hndl);
1740}
1741
1742/**************************************************************************
1743 * MMDRV_Open [internal]
1744 */
1745DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwFlags)
1746{
1747 DWORD dwRet = MMSYSERR_BADDEVICEID;
1748 DWORD dwInstance;
1749 WINE_LLTYPE* llType = &llTypes[mld->type];
1750
1751 mld->dwDriverInstance = (DWORD)&dwInstance;
1752
1753 if (mld->uDeviceID == (UINT)-1) {
1754 TRACE("MAPPER mode requested !\n");
1755 /* check if mapper is supported by type */
1756 if (llType->bSupportMapper) {
1757 if (llType->nMapper == -1) {
1758 /* no driver for mapper has been loaded, try a dumb implementation */
1759 TRACE("No mapper loaded, doing it by hand\n");
1760 for (mld->uDeviceID = 0; mld->uDeviceID < llType->wMaxId; mld->uDeviceID++) {
1761 if ((dwRet = MMDRV_Open(mld, wMsg, dwParam1, dwFlags)) == MMSYSERR_NOERROR) {
1762 /* to share this function epilog */
1763 dwInstance = mld->dwDriverInstance;
1764 break;
1765 }
1766 }
1767 } else {
Eric Pouech31a19331999-11-21 00:51:05 +00001768 mld->uDeviceID = (UINT16)-1;
Eric Pouech4853b6d1999-09-22 16:52:47 +00001769 mld->mmdIndex = llType->lpMlds[-1].mmdIndex;
1770 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
1771 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
1772 }
1773 }
1774 } else {
1775 if (mld->uDeviceID < llType->wMaxId) {
1776 mld->mmdIndex = llType->lpMlds[mld->uDeviceID].mmdIndex;
1777 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
1778 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
1779 }
1780 }
1781 if (dwRet == MMSYSERR_NOERROR)
1782 mld->dwDriverInstance = dwInstance;
1783 return dwRet;
1784}
1785
1786/**************************************************************************
1787 * MMDRV_Close [internal]
1788 */
1789DWORD MMDRV_Close(LPWINE_MLD mld, UINT wMsg)
1790{
1791 return MMDRV_Message(mld, wMsg, 0L, 0L, TRUE);
1792}
1793
1794/**************************************************************************
Eric Pouech31a19331999-11-21 00:51:05 +00001795 * MMDRV_GetByID [internal]
Eric Pouech4853b6d1999-09-22 16:52:47 +00001796 */
1797LPWINE_MLD MMDRV_GetByID(UINT uDevID, UINT type)
1798{
Eric Pouech31a19331999-11-21 00:51:05 +00001799 if (uDevID < llTypes[type].wMaxId)
1800 return &llTypes[type].lpMlds[uDevID];
1801 if ((uDevID == (UINT16)-1 || uDevID == (UINT)-1) && llTypes[type].nMapper != -1)
1802 return &llTypes[type].lpMlds[-1];
1803 return NULL;
Eric Pouech4853b6d1999-09-22 16:52:47 +00001804}
1805
1806/**************************************************************************
1807 * MMDRV_Get [internal]
1808 */
1809LPWINE_MLD MMDRV_Get(HANDLE hndl, UINT type, BOOL bCanBeID)
1810{
1811 LPWINE_MLD mld = NULL;
1812
1813 assert(type < MMDRV_MAX);
1814
1815 if ((UINT)hndl >= llTypes[type].wMaxId) {
1816 mld = (LPWINE_MLD)USER_HEAP_LIN_ADDR(hndl);
1817
Eric Pouech31a19331999-11-21 00:51:05 +00001818 if (!IsBadWritePtr(mld, sizeof(*mld)) && mld->type != type) mld = NULL;
1819 }
1820 if (mld == NULL && bCanBeID) {
Eric Pouech4853b6d1999-09-22 16:52:47 +00001821 mld = MMDRV_GetByID((UINT)hndl, type);
1822 }
1823 return mld;
1824}
1825
1826/**************************************************************************
1827 * MMDRV_GetRelated [internal]
1828 */
1829LPWINE_MLD MMDRV_GetRelated(HANDLE hndl, UINT srcType,
1830 BOOL bSrcCanBeID, UINT dstType)
1831{
1832 LPWINE_MLD mld;
1833
1834 if ((mld = MMDRV_Get(hndl, srcType, bSrcCanBeID)) != NULL) {
1835 WINE_MM_DRIVER_PART* part = &MMDrvs[mld->mmdIndex].parts[dstType];
1836 if (part->nIDMin < part->nIDMax)
1837 return MMDRV_GetByID(part->nIDMin, dstType);
1838 }
1839 return NULL;
1840}
1841
1842/**************************************************************************
1843 * MMDRV_PhysicalFeatures [internal]
1844 */
1845UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1,
1846 DWORD dwParam2)
1847{
1848 WINE_MM_DRIVER* lpDrv = &MMDrvs[mld->mmdIndex];
1849
1850 TRACE("(%p, %04x, %08lx, %08lx)\n", mld, uMsg, dwParam1, dwParam2);
1851
1852 /* all those function calls are undocumented */
1853 switch (uMsg) {
Eric Pouech31a19331999-11-21 00:51:05 +00001854 case 0x801: /* DRV_QUERYDRVENTRY */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001855 strncpy((LPSTR)dwParam1, lpDrv->name, LOWORD(dwParam2));
1856 break;
Eric Pouech31a19331999-11-21 00:51:05 +00001857 case 0x802: /* DRV_QUERYDEVNODE */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001858 *(LPDWORD)dwParam1 = 0L; /* should be DevNode */
1859 break;
Eric Pouech31a19331999-11-21 00:51:05 +00001860 case 0x803: /* DRV_QUERYNAME */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001861 WARN("NIY 0x803\n");
1862 break;
Eric Pouech31a19331999-11-21 00:51:05 +00001863 case 0x804: /* DRV_QUERYDRIVERIDS */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001864 WARN("NIY call VxD\n");
1865 /* should call VxD MMDEVLDR with (DevNode, dwParam1 and dwParam2) as pmts
1866 * dwParam1 is buffer and dwParam2 is sizeof buffer
1867 * I don't know where the result is stored though
1868 */
1869 break;
Eric Pouech31a19331999-11-21 00:51:05 +00001870 case 0x805: /* DRV_QUERYMAPPABLE */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001871 return (lpDrv->bIsMapper) ? 2 : 0;
1872 default:
1873 WARN("Unknown call %04x\n", uMsg);
1874 return MMSYSERR_INVALPARAM;
1875 }
1876 return 0L;
1877}
1878
1879/**************************************************************************
1880 * MMDRV_InitPerType [internal]
1881 */
Eric Pouech31655a61999-09-27 13:34:21 +00001882static BOOL MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv, UINT num,
Eric Pouech4853b6d1999-09-22 16:52:47 +00001883 UINT type, UINT wMsg)
1884{
1885 WINE_MM_DRIVER_PART* part = &lpDrv->parts[type];
Eric Pouech31655a61999-09-27 13:34:21 +00001886 DWORD ret;
1887 UINT count = 0;
1888 int i, k;
Eric Pouech4853b6d1999-09-22 16:52:47 +00001889
1890 part->nIDMin = part->nIDMax = 0;
1891
1892 /* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
1893 /* the DRVM_ENABLE is only required when the PnP node is non zero */
1894
1895 if (lpDrv->bIs32 && part->u.fnMessage32) {
1896 ret = part->u.fnMessage32(0, DRVM_INIT, 0L, 0L, 0L);
1897 TRACE("DRVM_INIT => %08lx\n", ret);
1898#if 0
1899 ret = part->u.fnMessage32(0, DRVM_ENABLE, 0L, 0L, 0L);
1900 TRACE("DRVM_ENABLE => %08lx\n", ret);
1901#endif
1902 count = part->u.fnMessage32(0, wMsg, 0L, 0L, 0L);
1903 }
1904
1905 if (!lpDrv->bIs32 && part->u.fnMessage16) {
1906 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
1907 0, DRVM_INIT, 0L, 0L, 0L);
1908 TRACE("DRVM_INIT => %08lx\n", ret);
1909#if 0
1910 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
1911 0, DRVM_ENABLE, 0L, 0L, 0L);
1912 TRACE("DRVM_ENABLE => %08lx\n", ret);
1913#endif
1914 count = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
1915 0, wMsg, 0L, 0L, 0L);
1916 }
1917
1918 TRACE("Got %u dev for (%s:%s)\n", count, lpDrv->name, llTypes[type].name);
Eric Pouech31655a61999-09-27 13:34:21 +00001919 if (count == 0)
1920 return FALSE;
1921
1922 /* got some drivers */
1923 if (lpDrv->bIsMapper) {
1924 if (llTypes[type].nMapper != -1)
1925 ERR("Two mappers for type %s (%d, %s)\n",
1926 llTypes[type].name, llTypes[type].nMapper, lpDrv->name);
1927 if (count > 1)
1928 ERR("Strange: mapper with %d > 1 devices\n", count);
1929 llTypes[type].nMapper = num;
1930 } else {
1931 part->nIDMin = llTypes[type].wMaxId;
1932 llTypes[type].wMaxId += count;
1933 part->nIDMax = llTypes[type].wMaxId;
Eric Pouech4853b6d1999-09-22 16:52:47 +00001934 }
Eric Pouech31655a61999-09-27 13:34:21 +00001935 TRACE("Setting min=%d max=%d (ttop=%d) for (%s:%s)\n",
1936 part->nIDMin, part->nIDMax, llTypes[type].wMaxId,
1937 lpDrv->name, llTypes[type].name);
1938 /* realloc translation table */
1939 llTypes[type].lpMlds = (LPWINE_MLD)
1940 HeapReAlloc(SystemHeap, 0, (llTypes[type].lpMlds) ? llTypes[type].lpMlds - 1 : NULL,
1941 sizeof(WINE_MLD) * (llTypes[type].wMaxId + 1)) + 1;
1942 /* re-build the translation table */
1943 if (llTypes[type].nMapper != -1) {
1944 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].name, -1, MMDrvs[llTypes[type].nMapper].name);
Eric Pouech31a19331999-11-21 00:51:05 +00001945 llTypes[type].lpMlds[-1].uDeviceID = (UINT16)-1;
Eric Pouech31655a61999-09-27 13:34:21 +00001946 llTypes[type].lpMlds[-1].type = type;
1947 llTypes[type].lpMlds[-1].mmdIndex = llTypes[type].nMapper;
1948 llTypes[type].lpMlds[-1].dwDriverInstance = 0;
1949 }
1950 for (i = k = 0; i <= num; i++) {
1951 while (MMDrvs[i].parts[type].nIDMin <= k && k < MMDrvs[i].parts[type].nIDMax) {
1952 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].name, k, MMDrvs[i].name);
1953 llTypes[type].lpMlds[k].uDeviceID = k;
1954 llTypes[type].lpMlds[k].type = type;
1955 llTypes[type].lpMlds[k].mmdIndex = i;
1956 llTypes[type].lpMlds[k].dwDriverInstance = 0;
1957 k++;
1958 }
1959 }
1960 return TRUE;
Eric Pouech4853b6d1999-09-22 16:52:47 +00001961}
1962
1963/**************************************************************************
1964 * MMDRV_Install [internal]
1965 */
1966static BOOL MMDRV_Install(LPCSTR name, int num, BOOL bIsMapper)
1967{
1968 int count = 0;
1969 char buffer[128];
1970 HMODULE hModule;
1971 LPWINE_MM_DRIVER lpDrv = &MMDrvs[num];
Eric Pouech4853b6d1999-09-22 16:52:47 +00001972
1973 TRACE("('%s');\n", name);
1974
1975 memset(lpDrv, 0, sizeof(*lpDrv));
1976
1977 /* First load driver */
1978 if ((lpDrv->hDrvr = OpenDriverA(name, 0, 0)) == 0) {
1979 WARN("Couldn't open driver '%s'\n", name);
1980 return FALSE;
1981 }
1982
1983 /* Then look for xxxMessage functions */
1984#define AA(_w,_x,_y,_z) \
1985 func = (WINEMM_msgFunc##_y) _z (hModule, #_x); \
1986 if (func != NULL) \
1987 { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
1988 TRACE("Got %d bit func '%s'\n", _y, #_x); }
1989
1990 if ((DRIVER_GetType(lpDrv->hDrvr) & WINE_DI_TYPE_MASK) == WINE_DI_TYPE_32) {
1991 WINEMM_msgFunc32 func;
1992
1993 lpDrv->bIs32 = TRUE;
1994 if ((hModule = GetDriverModuleHandle(lpDrv->hDrvr))) {
1995#define A(_x,_y) AA(_x,_y,32,GetProcAddress)
1996 A(MMDRV_AUX, auxMessage);
1997 A(MMDRV_MIXER, mixMessage);
1998 A(MMDRV_MIDIIN, midMessage);
1999 A(MMDRV_MIDIOUT, modMessage);
2000 A(MMDRV_WAVEIN, widMessage);
2001 A(MMDRV_WAVEOUT, wodMessage);
2002#undef A
2003 }
2004 } else {
2005 WINEMM_msgFunc16 func;
2006
2007 /*
2008 * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
2009 * The beginning of the module description indicates the driver supports
2010 * waveform, auxiliary, and mixer devices. Use one of the following
2011 * device-type names, followed by a colon (:) to indicate the type of
2012 * device your driver supports. If the driver supports more than one
2013 * type of device, separate each device-type name with a comma (,).
2014 *
2015 * wave for waveform audio devices
2016 * wavemapper for wave mappers
2017 * midi for MIDI audio devices
2018 * midimapper for midi mappers
2019 * aux for auxiliary audio devices
2020 * mixer for mixer devices
2021 */
2022
2023 lpDrv->bIs32 = FALSE;
2024 if ((hModule = GetDriverModuleHandle16(lpDrv->hDrvr))) {
2025#define A(_x,_y) AA(_x,_y,16,WIN32_GetProcAddress16)
2026 A(MMDRV_AUX, auxMessage);
2027 A(MMDRV_MIXER, mixMessage);
2028 A(MMDRV_MIDIIN, midMessage);
2029 A(MMDRV_MIDIOUT, modMessage);
2030 A(MMDRV_WAVEIN, widMessage);
2031 A(MMDRV_WAVEOUT, wodMessage);
2032#undef A
2033 }
2034 }
2035#undef AA
2036
2037 if (TRACE_ON(mmsys)) {
2038 if ((lpDrv->bIs32) ? MMDRV_GetDescription32(name, buffer, sizeof(buffer)) :
2039 MMDRV_GetDescription16(name, buffer, sizeof(buffer)))
2040 TRACE("%s => %s\n", name, buffer);
2041 else
2042 TRACE("%s => No description\n", name);
2043 }
2044
2045 if (!count) {
2046 CloseDriver(lpDrv->hDrvr, 0, 0);
2047 WARN("No message functions found\n");
2048 return FALSE;
2049 }
2050
2051 /* FIXME: being a mapper or not should be known by another way */
2052 /* it's known for NE drvs (the description is of the form '*mapper: *'
2053 * I don't have any clue for PE drvs
2054 * on Win 9x, the value is gotten from the key mappable under
2055 * HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\MediaResources\
2056 */
2057 lpDrv->bIsMapper = bIsMapper;
2058 lpDrv->name = HEAP_strdupA(GetProcessHeap(), 0, name);
2059
2060 /* Finish init and get the count of the devices */
2061 MMDRV_InitPerType(lpDrv, num, MMDRV_AUX, AUXDM_GETNUMDEVS);
2062 MMDRV_InitPerType(lpDrv, num, MMDRV_MIXER, MXDM_GETNUMDEVS);
2063 MMDRV_InitPerType(lpDrv, num, MMDRV_MIDIIN, MIDM_GETNUMDEVS);
2064 MMDRV_InitPerType(lpDrv, num, MMDRV_MIDIOUT, MODM_GETNUMDEVS);
2065 MMDRV_InitPerType(lpDrv, num, MMDRV_WAVEIN, WIDM_GETNUMDEVS);
2066 MMDRV_InitPerType(lpDrv, num, MMDRV_WAVEOUT, WODM_GETNUMDEVS);
Eric Pouech31655a61999-09-27 13:34:21 +00002067 /* FIXME: if all those func calls return FALSE, then the driver must be unloaded */
Eric Pouech4853b6d1999-09-22 16:52:47 +00002068 return TRUE;
2069}
2070
2071/**************************************************************************
2072 * MMDRV_Init [internal]
2073 */
2074BOOL MMDRV_Init(void)
2075{
2076 int num = 0;
2077
2078 /* FIXME: this should be moved to init files;
2079 * - either .winerc/wine.conf
2080 * - or made of registry keys
2081 * this is a temporary hack, shall be removed anytime now
2082 */
2083 /* first load hardware drivers */
2084 if (MMDRV_Install("wineoss.drv", num, FALSE)) num++;
2085
2086 /* finish with mappers */
2087 if (MMDRV_Install("msacm.drv", num, TRUE )) num++;
2088 if (MMDRV_Install("midimap.drv", num, TRUE )) num++;
2089
2090
2091 /* be sure that size of MMDrvs matches the max number of loadable drivers !!
2092 * if not just increase size of MMDrvs */
2093 assert(num <= sizeof(MMDrvs)/sizeof(MMDrvs[0]));
2094
2095 return TRUE;
2096}