blob: 7dba951f16b211c75d790e798ea13e478ac7217d [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
Eric Pouechaa5f5a31999-12-05 02:17:40 +0000343 switch (uMsg) {
344 case MIM_OPEN:
345 case MIM_CLOSE:
346 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
347
348 case MIM_DATA:
349 case MIM_MOREDATA:
350 case MIM_ERROR:
351 /* dwParam1 & dwParam2 are are data, nothing to do */
352 break;
353 case MIM_LONGDATA:
354 case MIM_LONGERROR:
355 /* dwParam1 points to a MidiHdr, work to be done !!! */
356 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
357 /* initial map is: 32 => 16 */
358 LPMIDIHDR wh16 = (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1);
359 LPMIDIHDR wh32 = *(LPMIDIHDR*)((LPSTR)wh16 - sizeof(LPMIDIHDR));
360
361 dwParam1 = (DWORD)wh32;
362 wh32->dwFlags = wh16->dwFlags;
363 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
364 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
365 /* initial map is: 16 => 32 */
366 LPMIDIHDR wh32 = (LPMIDIHDR)(dwParam1);
367 LPMIDIHDR segwh16 = *(LPMIDIHDR*)((LPSTR)wh32 - sizeof(LPMIDIHDR));
368 LPMIDIHDR wh16 = PTR_SEG_TO_LIN(segwh16);
369
370 dwParam1 = (DWORD)segwh16;
371 wh16->dwFlags = wh32->dwFlags;
372 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
373 }
374 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
375 break;
376 /* case MOM_POSITIONCB: */
377 default:
378 ERR("Unknown msg %u\n", uMsg);
379 }
380
Eric Pouech4853b6d1999-09-22 16:52:47 +0000381 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
382}
383
384/* =================================
385 * M I D I O U T M A P P E R S
386 * ================================= */
387
388/**************************************************************************
389 * MMDRV_MidiOut_Map16To32A [internal]
390 */
391static MMDRV_MapType MMDRV_MidiOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
392{
393 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
394
395 switch (wMsg) {
396 case MODM_GETNUMDEVS:
397 case MODM_DATA:
398 case MODM_RESET:
399 case MODM_SETVOLUME:
400 ret = MMDRV_MAP_OK;
401 break;
402
403 case MODM_OPEN:
404 case MODM_CLOSE:
405 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
406 break;
407
408 case MODM_GETDEVCAPS:
409 {
410 LPMIDIOUTCAPSA moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSA));
411 LPMIDIOUTCAPS16 moc16 = PTR_SEG_TO_LIN(*lpParam1);
412
413 if (moc32) {
414 *(LPMIDIOUTCAPS16*)moc32 = moc16;
415 moc32 = (LPMIDIOUTCAPSA)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
416 *lpParam1 = (DWORD)moc32;
417 *lpParam2 = sizeof(MIDIOUTCAPSA);
418
419 ret = MMDRV_MAP_OKMEM;
420 } else {
421 ret = MMDRV_MAP_NOMEM;
422 }
423 }
424 break;
425 case MODM_PREPARE:
426 case MODM_UNPREPARE:
427 case MODM_LONGDATA:
428 case MODM_GETVOLUME:
429 case MODM_CACHEPATCHES:
430 case MODM_CACHEDRUMPATCHES:
431 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000432 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000433 break;
434 }
435 return ret;
436}
437
438/**************************************************************************
439 * MMDRV_MidiOut_UnMap16To32A [internal]
440 */
441static MMDRV_MapType MMDRV_MidiOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
442{
443 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
444
445 switch (wMsg) {
446 case MODM_GETNUMDEVS:
447 case MODM_DATA:
448 case MODM_RESET:
449 case MODM_SETVOLUME:
450 ret = MMDRV_MAP_OK;
451 break;
452
453 case MODM_OPEN:
454 case MODM_CLOSE:
455 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
456 break;
457
458 case MODM_GETDEVCAPS:
459 {
460 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)(*lpParam1);
461 LPMIDIOUTCAPS16 moc16 = *(LPMIDIOUTCAPS16*)((LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
462
463 moc16->wMid = moc32->wMid;
464 moc16->wPid = moc32->wPid;
465 moc16->vDriverVersion = moc32->vDriverVersion;
466 strcpy(moc16->szPname, moc32->szPname);
467 moc16->wTechnology = moc32->wTechnology;
468 moc16->wVoices = moc32->wVoices;
469 moc16->wNotes = moc32->wNotes;
470 moc16->wChannelMask = moc32->wChannelMask;
471 moc16->dwSupport = moc32->dwSupport;
472 HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
473 ret = MMDRV_MAP_OK;
474 }
475 break;
476 case MODM_PREPARE:
477 case MODM_UNPREPARE:
478 case MODM_LONGDATA:
479 case MODM_GETVOLUME:
480 case MODM_CACHEPATCHES:
481 case MODM_CACHEDRUMPATCHES:
482 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000483 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000484 break;
485 }
486 return ret;
487}
488
489/**************************************************************************
490 * MMDRV_MidiOut_Map32ATo16 [internal]
491 */
492static MMDRV_MapType MMDRV_MidiOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
493{
494 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
495
496 switch (wMsg) {
497 case MODM_CLOSE:
498 case MODM_GETNUMDEVS:
499 case MODM_DATA:
500 case MODM_RESET:
501 case MODM_SETVOLUME:
502 ret = MMDRV_MAP_OK;
503 break;
504 case MODM_GETDEVCAPS:
505 {
506 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)*lpParam1;
507 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPMIDIOUTCAPSA) + sizeof(MIDIOUTCAPS16));
508
509 if (ptr) {
510 *(LPMIDIOUTCAPSA*)ptr = moc32;
511 ret = MMDRV_MAP_OKMEM;
512 } else {
513 ret = MMDRV_MAP_NOMEM;
514 }
515 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIOUTCAPSA);
516 *lpParam2 = sizeof(MIDIOUTCAPS16);
517 }
518 break;
519 case MODM_OPEN:
520 case MODM_PREPARE:
521 case MODM_UNPREPARE:
522 case MODM_LONGDATA:
523 case MODM_GETVOLUME:
524 case MODM_CACHEPATCHES:
525 case MODM_CACHEDRUMPATCHES:
526 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000527 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000528 break;
529 }
530 return ret;
531}
532
533/**************************************************************************
534 * MMDRV_MidiOut_UnMap32ATo16 [internal]
535 */
536static MMDRV_MapType MMDRV_MidiOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
537{
538 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
539
540 switch (wMsg) {
541 case MODM_CLOSE:
542 case MODM_GETNUMDEVS:
543 case MODM_DATA:
544 case MODM_RESET:
545 case MODM_SETVOLUME:
546 ret = MMDRV_MAP_OK;
547 break;
548 case MODM_GETDEVCAPS:
549 {
550 LPMIDIOUTCAPS16 moc16 = (LPMIDIOUTCAPS16)PTR_SEG_TO_LIN(*lpParam1);
551 LPSTR ptr = (LPSTR)moc16 - sizeof(LPMIDIOUTCAPSA);
552 LPMIDIOUTCAPSA moc32 = *(LPMIDIOUTCAPSA*)ptr;
553
554 moc32->wMid = moc16->wMid;
555 moc32->wPid = moc16->wPid;
556 moc32->vDriverVersion = moc16->vDriverVersion;
557 strcpy(moc32->szPname, moc16->szPname);
558 moc32->wTechnology = moc16->wTechnology;
559 moc32->wVoices = moc16->wVoices;
560 moc32->wNotes = moc16->wNotes;
561 moc32->wChannelMask = moc16->wChannelMask;
562 moc32->dwSupport = moc16->dwSupport;
563
564 if (!SEGPTR_FREE(ptr))
565 FIXME("bad free line=%d\n", __LINE__);
566 ret = MMDRV_MAP_OK;
567 }
568 break;
569 case MODM_OPEN:
570 case MODM_PREPARE:
571 case MODM_UNPREPARE:
572 case MODM_LONGDATA:
573 case MODM_GETVOLUME:
574 case MODM_CACHEPATCHES:
575 case MODM_CACHEDRUMPATCHES:
576 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000577 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000578 break;
579 }
580 return ret;
581}
582
583/**************************************************************************
584 * MMDRV_MidiOut_Callback [internal]
585 */
586static void CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
587{
588 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
589
590 switch (uMsg) {
591 case MOM_OPEN:
592 case MOM_CLOSE:
593 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
594 break;
595 case MOM_DONE:
596 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
597 /* initial map is: 32 => 16 */
598 LPMIDIHDR wh16 = (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1);
599 LPMIDIHDR wh32 = *(LPMIDIHDR*)((LPSTR)wh16 - sizeof(LPMIDIHDR));
600
601 dwParam1 = (DWORD)wh32;
602 wh32->dwFlags = wh16->dwFlags;
603 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
604 /* initial map is: 16 => 32 */
605 LPMIDIHDR wh32 = (LPMIDIHDR)(dwParam1);
606 LPMIDIHDR segwh16 = *(LPMIDIHDR*)((LPSTR)wh32 - sizeof(LPMIDIHDR));
607 LPMIDIHDR wh16 = PTR_SEG_TO_LIN(segwh16);
608
609 dwParam1 = (DWORD)segwh16;
610 wh16->dwFlags = wh32->dwFlags;
611 }
612 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
613 break;
614 /* case MOM_POSITIONCB: */
615 default:
616 ERR("Unknown msg %u\n", uMsg);
617 }
618
619 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
620}
621
622/* =================================
623 * W A V E I N M A P P E R S
624 * ================================= */
625
626/**************************************************************************
627 * MMDRV_WaveIn_Map16To32A [internal]
628 */
629static MMDRV_MapType MMDRV_WaveIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
630{
631 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
632
633 switch (wMsg) {
634 case WIDM_GETNUMDEVS:
635 case WIDM_RESET:
636 case WIDM_START:
637 case WIDM_STOP:
638 ret = MMDRV_MAP_OK;
639 break;
640 case WIDM_OPEN:
641 case WIDM_CLOSE:
642 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
643 break;
644 case WIDM_GETDEVCAPS:
645 {
646 LPWAVEINCAPSA wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSA));
647 LPWAVEINCAPS16 wic16 = PTR_SEG_TO_LIN(*lpParam1);
648
649 if (wic32) {
650 *(LPWAVEINCAPS16*)wic32 = wic16;
651 wic32 = (LPWAVEINCAPSA)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
652 *lpParam1 = (DWORD)wic32;
653 *lpParam2 = sizeof(WAVEINCAPSA);
654
655 ret = MMDRV_MAP_OKMEM;
656 } else {
657 ret = MMDRV_MAP_NOMEM;
658 }
659 }
660 break;
661 case WIDM_GETPOS:
662 {
663 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
664 LPMMTIME16 mmt16 = PTR_SEG_TO_LIN(*lpParam1);
665
666 if (mmt32) {
667 *(LPMMTIME16*)mmt32 = mmt16;
668 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
669
670 mmt32->wType = mmt16->wType;
671 *lpParam1 = (DWORD)mmt32;
672 *lpParam2 = sizeof(MMTIME);
673
674 ret = MMDRV_MAP_OKMEM;
675 } else {
676 ret = MMDRV_MAP_NOMEM;
677 }
678 }
679 break;
680 case WIDM_PREPARE:
681 {
682 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
683 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
684
685 if (wh32) {
686 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
687 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
688 wh32->lpData = PTR_SEG_TO_LIN(wh16->lpData);
689 wh32->dwBufferLength = wh16->dwBufferLength;
690 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
691 wh32->dwUser = wh16->dwUser;
692 wh32->dwFlags = wh16->dwFlags;
693 wh32->dwLoops = wh16->dwLoops;
694 /* FIXME: nothing on wh32->lpNext */
695 /* could link the wh32->lpNext at this level for memory house keeping */
696 wh16->lpNext = wh32; /* for reuse in unprepare and write */
Eric Pouech4853b6d1999-09-22 16:52:47 +0000697 *lpParam1 = (DWORD)wh32;
698 *lpParam2 = sizeof(WAVEHDR);
699
700 ret = MMDRV_MAP_OKMEM;
701 } else {
702 ret = MMDRV_MAP_NOMEM;
703 }
704 }
705 break;
706 case WIDM_ADDBUFFER:
707 case WIDM_UNPREPARE:
708 {
709 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
710 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
711
712 *lpParam1 = (DWORD)wh32;
713 *lpParam2 = sizeof(WAVEHDR);
714 ret = MMDRV_MAP_OKMEM;
715 }
716 break;
717 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000718 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
719 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000720 break;
721 }
722 return ret;
723}
724
725/**************************************************************************
726 * MMDRV_WaveIn_UnMap16To32A [internal]
727 */
728static MMDRV_MapType MMDRV_WaveIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
729{
730 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
731
732 switch (wMsg) {
733 case WIDM_GETNUMDEVS:
734 case WIDM_RESET:
735 case WIDM_START:
736 case WIDM_STOP:
737 ret = MMDRV_MAP_OK;
738 break;
739 case WIDM_OPEN:
740 case WIDM_CLOSE:
741 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
742 break;
743 case WIDM_GETDEVCAPS:
744 {
745 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)(*lpParam1);
746 LPWAVEINCAPS16 wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
747
748 wic16->wMid = wic32->wMid;
749 wic16->wPid = wic32->wPid;
750 wic16->vDriverVersion = wic32->vDriverVersion;
751 strcpy(wic16->szPname, wic32->szPname);
752 wic16->dwFormats = wic32->dwFormats;
753 wic16->wChannels = wic32->wChannels;
754 HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
755 ret = MMDRV_MAP_OK;
756 }
757 break;
758 case WIDM_GETPOS:
759 {
760 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
761 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
762
763 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
764 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
765 ret = MMDRV_MAP_OK;
766 }
767 break;
768 case WIDM_ADDBUFFER:
769 case WIDM_PREPARE:
770 case WIDM_UNPREPARE:
771 {
772 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
773 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
774
775 assert(wh16->lpNext == wh32);
776 wh16->dwBufferLength = wh32->dwBufferLength;
777 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
778 wh16->dwUser = wh32->dwUser;
779 wh16->dwFlags = wh32->dwFlags;
780 wh16->dwLoops = wh32->dwLoops;
781
782 if (wMsg == WIDM_UNPREPARE) {
783 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
784 wh16->lpNext = 0;
785 }
786 ret = MMDRV_MAP_OK;
787 }
788 break;
789 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000790 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000791 break;
792 }
793 return ret;
794}
795
796/**************************************************************************
797 * MMDRV_WaveIn_Map32ATo16 [internal]
798 */
799static MMDRV_MapType MMDRV_WaveIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
800{
801 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
802
803 switch (wMsg) {
804 case WIDM_CLOSE:
805 case WIDM_GETNUMDEVS:
806 case WIDM_RESET:
807 case WIDM_START:
808 case WIDM_STOP:
809 ret = MMDRV_MAP_OK;
810 break;
811
812 case WIDM_OPEN:
813 {
814 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
815 int sz = sizeof(WAVEFORMATEX);
816 LPVOID ptr;
817 LPWAVEOPENDESC16 wod16;
818
819 /* allocated data are mapped as follows:
820 LPWAVEOPENDESC ptr to orig lParam1
821 DWORD ptr to orig dwUser, which is a pointer to DWORD:driver dwInstance
822 DWORD dwUser passed to driver
823 WAVEOPENDESC16 wod16: openDesc passed to driver
824 WAVEFORMATEX openDesc->lpFormat passed to driver
825 xxx extra bytes to WAVEFORMATEX
826 */
827 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
828 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
829 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
830 }
831
832 ptr = SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
833
834 if (ptr) {
835 *(LPWAVEOPENDESC*)ptr = wod32;
836 *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
837 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
838
839 wod16->hWave = wod32->hWave;
840 wod16->lpFormat = (LPWAVEFORMATEX)((DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
841 memcpy(wod16 + 1, wod32->lpFormat, sz);
842
843 wod16->dwCallback = wod32->dwCallback;
844 wod16->dwInstance = wod32->dwInstance;
845 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
846 wod16->dnDevNode = wod32->dnDevNode;
847
848 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
849 *lpdwUser = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
850
851 ret = MMDRV_MAP_OKMEM;
852 } else {
853 ret = MMDRV_MAP_NOMEM;
854 }
855 }
856 break;
857 case WIDM_PREPARE:
858 {
859 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
860 LPWAVEHDR wh16;
861 LPVOID ptr = SEGPTR_ALLOC(sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
862
863 if (ptr) {
864 *(LPWAVEHDR*)ptr = wh32;
865 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
866 wh16->lpData = (LPSTR)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
867 /* data will be copied on WODM_WRITE */
868 wh16->dwBufferLength = wh32->dwBufferLength;
869 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
870 wh16->dwUser = wh32->dwUser;
871 wh16->dwFlags = wh32->dwFlags;
872 wh16->dwLoops = wh32->dwLoops;
873 /* FIXME: nothing on wh32->lpNext */
874 /* could link the wh32->lpNext at this level for memory house keeping */
875 wh32->lpNext = wh16; /* for reuse in unprepare and write */
Eric Pouech4853b6d1999-09-22 16:52:47 +0000876 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
877 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
878 wh32->dwBufferLength, (DWORD)wh32->lpData);
879 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
880 *lpParam2 = sizeof(WAVEHDR);
881
882 ret = MMDRV_MAP_OKMEM;
883 } else {
884 ret = MMDRV_MAP_NOMEM;
885 }
886 }
887 break;
888 case WIDM_ADDBUFFER:
889 case WIDM_UNPREPARE:
890 {
891 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
892 LPWAVEHDR wh16 = wh32->lpNext;
893 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
894
895 assert(*(LPWAVEHDR*)ptr == wh32);
896
897 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
898 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
899 wh32->dwBufferLength, (DWORD)wh32->lpData);
900
901 if (wMsg == WODM_WRITE)
902 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
903
904 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
905 *lpParam2 = sizeof(WAVEHDR);
906 ret = MMDRV_MAP_OKMEM;
907 }
908 break;
909 case WIDM_GETDEVCAPS:
910 {
911 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)*lpParam1;
912 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPWAVEINCAPSA) + sizeof(WAVEINCAPS16));
913
914 if (ptr) {
915 *(LPWAVEINCAPSA*)ptr = wic32;
916 ret = MMDRV_MAP_OKMEM;
917 } else {
918 ret = MMDRV_MAP_NOMEM;
919 }
920 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEINCAPSA);
921 *lpParam2 = sizeof(WAVEINCAPS16);
922 }
923 break;
924 case WIDM_GETPOS:
925 {
926 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
927 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPMMTIME) + sizeof(MMTIME16));
928 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
929
930 if (ptr) {
931 *(LPMMTIME*)ptr = mmt32;
932 mmt16->wType = mmt32->wType;
933 ret = MMDRV_MAP_OKMEM;
934 } else {
935 ret = MMDRV_MAP_NOMEM;
936 }
937 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMMTIME);
938 *lpParam2 = sizeof(MMTIME16);
939 }
940 break;
941 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000942 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000943 break;
944 }
945 return ret;
946}
947
948/**************************************************************************
949 * MMDRV_WaveIn_UnMap32ATo16 [internal]
950 */
951static MMDRV_MapType MMDRV_WaveIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
952{
953 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
954
955 switch (wMsg) {
956 case WIDM_CLOSE:
957 case WIDM_GETNUMDEVS:
958 case WIDM_RESET:
959 case WIDM_START:
960 case WIDM_STOP:
961 ret = MMDRV_MAP_OK;
962 break;
963
964 case WIDM_OPEN:
965 {
966 LPWAVEOPENDESC16 wod16 = (LPWAVEOPENDESC16)PTR_SEG_TO_LIN(*lpParam1);
967 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
968 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
969
970 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
971 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
972
973 if (!SEGPTR_FREE(ptr))
974 FIXME("bad free line=%d\n", __LINE__);
975
976 ret = MMDRV_MAP_OK;
977 }
978 break;
979
980 case WIDM_ADDBUFFER:
981 case WIDM_PREPARE:
982 case WIDM_UNPREPARE:
983 {
984 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(*lpParam1);
985 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
986 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
987
988 assert(wh32->lpNext == wh16);
989 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
990 wh32->dwUser = wh16->dwUser;
991 wh32->dwFlags = wh16->dwFlags;
992 wh32->dwLoops = wh16->dwLoops;
993
994 if (wMsg == WODM_UNPREPARE) {
995 if (!SEGPTR_FREE(ptr))
996 FIXME("bad free line=%d\n", __LINE__);
997 wh32->lpNext = 0;
998 }
999 ret = MMDRV_MAP_OK;
1000 }
1001 break;
1002 case WIDM_GETDEVCAPS:
1003 {
1004 LPWAVEINCAPS16 wic16 = (LPWAVEINCAPS16)PTR_SEG_TO_LIN(*lpParam1);
1005 LPSTR ptr = (LPSTR)wic16 - sizeof(LPWAVEINCAPSA);
1006 LPWAVEINCAPSA wic32 = *(LPWAVEINCAPSA*)ptr;
1007
1008 wic32->wMid = wic16->wMid;
1009 wic32->wPid = wic16->wPid;
1010 wic32->vDriverVersion = wic16->vDriverVersion;
1011 strcpy(wic32->szPname, wic16->szPname);
1012 wic32->dwFormats = wic16->dwFormats;
1013 wic32->wChannels = wic16->wChannels;
1014 if (!SEGPTR_FREE(ptr))
1015 FIXME("bad free line=%d\n", __LINE__);
1016 ret = MMDRV_MAP_OK;
1017 }
1018 break;
1019 case WIDM_GETPOS:
1020 {
1021 LPMMTIME16 mmt16 = (LPMMTIME16)PTR_SEG_TO_LIN(*lpParam1);
1022 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1023 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1024
1025 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1026
1027 if (!SEGPTR_FREE(ptr))
1028 FIXME("bad free line=%d\n", __LINE__);
1029
1030 ret = MMDRV_MAP_OK;
1031 }
1032 break;
1033 default:
Eric Pouech31a19331999-11-21 00:51:05 +00001034 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +00001035 break;
1036 }
1037 return ret;
1038}
1039
1040/**************************************************************************
1041 * MMDRV_WaveIn_Callback [internal]
1042 */
1043static void CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1044{
1045 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1046
1047 switch (uMsg) {
1048 case WIM_OPEN:
1049 case WIM_CLOSE:
1050 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1051 break;
1052 case WIM_DATA:
1053 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1054 /* initial map is: 32 => 16 */
1055 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1);
1056 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1057
1058 dwParam1 = (DWORD)wh32;
1059 wh32->dwFlags = wh16->dwFlags;
1060 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1061 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1062 /* initial map is: 16 => 32 */
1063 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1064 LPWAVEHDR segwh16 = *(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1065 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(segwh16);
1066
1067 dwParam1 = (DWORD)segwh16;
1068 wh16->dwFlags = wh32->dwFlags;
1069 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1070 }
1071 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1072 break;
1073 default:
1074 ERR("Unknown msg %u\n", uMsg);
1075 }
1076
1077 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1078}
1079
1080/* =================================
1081 * W A V E O U T M A P P E R S
1082 * ================================= */
1083
1084/**************************************************************************
1085 * MMDRV_WaveOut_Map16To32A [internal]
1086 */
1087static MMDRV_MapType MMDRV_WaveOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1088{
1089 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1090
1091 switch (wMsg) {
1092 /* nothing to do */
1093 case WODM_BREAKLOOP:
1094 case WODM_CLOSE:
1095 case WODM_GETNUMDEVS:
1096 case WODM_PAUSE:
1097 case WODM_RESET:
1098 case WODM_RESTART:
1099 case WODM_SETPITCH:
1100 case WODM_SETPLAYBACKRATE:
1101 case WODM_SETVOLUME:
1102 ret = MMDRV_MAP_OK;
1103 break;
1104
1105 case WODM_GETPITCH:
1106 case WODM_GETPLAYBACKRATE:
1107 case WODM_GETVOLUME:
1108 case WODM_OPEN:
1109 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1110 break;
1111
1112 case WODM_GETDEVCAPS:
1113 {
1114 LPWAVEOUTCAPSA woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSA));
1115 LPWAVEOUTCAPS16 woc16 = PTR_SEG_TO_LIN(*lpParam1);
1116
1117 if (woc32) {
1118 *(LPWAVEOUTCAPS16*)woc32 = woc16;
1119 woc32 = (LPWAVEOUTCAPSA)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
1120 *lpParam1 = (DWORD)woc32;
1121 *lpParam2 = sizeof(WAVEOUTCAPSA);
1122
1123 ret = MMDRV_MAP_OKMEM;
1124 } else {
1125 ret = MMDRV_MAP_NOMEM;
1126 }
1127 }
1128 break;
1129 case WODM_GETPOS:
1130 {
1131 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
1132 LPMMTIME16 mmt16 = PTR_SEG_TO_LIN(*lpParam1);
1133
1134 if (mmt32) {
1135 *(LPMMTIME16*)mmt32 = mmt16;
1136 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
1137
1138 mmt32->wType = mmt16->wType;
1139 *lpParam1 = (DWORD)mmt32;
1140 *lpParam2 = sizeof(MMTIME);
1141
1142 ret = MMDRV_MAP_OKMEM;
1143 } else {
1144 ret = MMDRV_MAP_NOMEM;
1145 }
1146 }
1147 break;
1148 case WODM_PREPARE:
1149 {
1150 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
1151 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
1152
1153 if (wh32) {
1154 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
1155 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
1156 wh32->lpData = PTR_SEG_TO_LIN(wh16->lpData);
1157 wh32->dwBufferLength = wh16->dwBufferLength;
1158 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1159 wh32->dwUser = wh16->dwUser;
1160 wh32->dwFlags = wh16->dwFlags;
1161 wh32->dwLoops = wh16->dwLoops;
1162 /* FIXME: nothing on wh32->lpNext */
1163 /* could link the wh32->lpNext at this level for memory house keeping */
1164 wh16->lpNext = wh32; /* for reuse in unprepare and write */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001165 *lpParam1 = (DWORD)wh32;
1166 *lpParam2 = sizeof(WAVEHDR);
1167
1168 ret = MMDRV_MAP_OKMEM;
1169 } else {
1170 ret = MMDRV_MAP_NOMEM;
1171 }
1172 }
1173 break;
1174 case WODM_UNPREPARE:
1175 case WODM_WRITE:
1176 {
1177 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
1178 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
1179
1180 *lpParam1 = (DWORD)wh32;
1181 *lpParam2 = sizeof(WAVEHDR);
1182 ret = MMDRV_MAP_OKMEM;
1183 }
1184 break;
1185 default:
Eric Pouech31a19331999-11-21 00:51:05 +00001186 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +00001187 break;
1188 }
1189 return ret;
1190}
1191
1192/**************************************************************************
1193 * MMDRV_WaveOut_UnMap16To32A [internal]
1194 */
1195static MMDRV_MapType MMDRV_WaveOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1196{
1197 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1198
1199 switch (wMsg) {
1200 /* nothing to do */
1201 case WODM_BREAKLOOP:
1202 case WODM_CLOSE:
1203 case WODM_GETNUMDEVS:
1204 case WODM_PAUSE:
1205 case WODM_RESET:
1206 case WODM_RESTART:
1207 case WODM_SETPITCH:
1208 case WODM_SETPLAYBACKRATE:
1209 case WODM_SETVOLUME:
1210 ret = MMDRV_MAP_OK;
1211 break;
1212
1213 case WODM_GETPITCH:
1214 case WODM_GETPLAYBACKRATE:
1215 case WODM_GETVOLUME:
1216 case WODM_OPEN:
1217 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1218 break;
1219
1220 case WODM_GETDEVCAPS:
1221 {
1222 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)(*lpParam1);
1223 LPWAVEOUTCAPS16 woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1224
1225 woc16->wMid = woc32->wMid;
1226 woc16->wPid = woc32->wPid;
1227 woc16->vDriverVersion = woc32->vDriverVersion;
1228 strcpy(woc16->szPname, woc32->szPname);
1229 woc16->dwFormats = woc32->dwFormats;
1230 woc16->wChannels = woc32->wChannels;
1231 woc16->dwSupport = woc32->dwSupport;
1232 HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1233 ret = MMDRV_MAP_OK;
1234 }
1235 break;
1236 case WODM_GETPOS:
1237 {
1238 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
1239 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
1240
1241 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
1242 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1243 ret = MMDRV_MAP_OK;
1244 }
1245 break;
1246 case WODM_PREPARE:
1247 case WODM_UNPREPARE:
1248 case WODM_WRITE:
1249 {
1250 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1251 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1252
1253 assert(wh16->lpNext == wh32);
1254 wh16->dwBufferLength = wh32->dwBufferLength;
1255 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1256 wh16->dwUser = wh32->dwUser;
1257 wh16->dwFlags = wh32->dwFlags;
1258 wh16->dwLoops = wh32->dwLoops;
1259
1260 if (wMsg == WODM_UNPREPARE) {
1261 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1262 wh16->lpNext = 0;
1263 }
1264 ret = MMDRV_MAP_OK;
1265 }
1266 break;
1267 default:
Eric Pouech31a19331999-11-21 00:51:05 +00001268 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +00001269 break;
1270 }
1271 return ret;
1272}
1273
1274/**************************************************************************
1275 * MMDRV_WaveOut_Map32ATo16 [internal]
1276 */
1277static MMDRV_MapType MMDRV_WaveOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1278{
1279 MMDRV_MapType ret;
1280
1281 switch (wMsg) {
1282 /* nothing to do */
1283 case WODM_BREAKLOOP:
1284 case WODM_CLOSE:
1285 case WODM_GETNUMDEVS:
1286 case WODM_PAUSE:
1287 case WODM_RESET:
1288 case WODM_RESTART:
1289 case WODM_SETPITCH:
1290 case WODM_SETPLAYBACKRATE:
1291 case WODM_SETVOLUME:
1292 ret = MMDRV_MAP_OK;
1293 break;
1294
1295 case WODM_GETDEVCAPS:
1296 {
1297 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)*lpParam1;
1298 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPWAVEOUTCAPSA) + sizeof(WAVEOUTCAPS16));
1299
1300 if (ptr) {
1301 *(LPWAVEOUTCAPSA*)ptr = woc32;
1302 ret = MMDRV_MAP_OKMEM;
1303 } else {
1304 ret = MMDRV_MAP_NOMEM;
1305 }
1306 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOUTCAPSA);
1307 *lpParam2 = sizeof(WAVEOUTCAPS16);
1308 }
1309 break;
1310 case WODM_GETPITCH:
1311 FIXME("NIY: no conversion yet\n");
1312 ret = MMDRV_MAP_MSGERROR;
1313 break;
1314 case WODM_GETPLAYBACKRATE:
1315 FIXME("NIY: no conversion yet\n");
1316 ret = MMDRV_MAP_MSGERROR;
1317 break;
1318 case WODM_GETPOS:
1319 {
1320 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1321 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPMMTIME) + sizeof(MMTIME16));
1322 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1323
1324 if (ptr) {
1325 *(LPMMTIME*)ptr = mmt32;
1326 mmt16->wType = mmt32->wType;
1327 ret = MMDRV_MAP_OKMEM;
1328 } else {
1329 ret = MMDRV_MAP_NOMEM;
1330 }
1331 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMMTIME);
1332 *lpParam2 = sizeof(MMTIME16);
1333 }
1334 break;
1335 case WODM_GETVOLUME:
1336 FIXME("NIY: no conversion yet\n");
1337 ret = MMDRV_MAP_MSGERROR;
1338 break;
1339 case WODM_OPEN:
1340 {
1341 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1342 int sz = sizeof(WAVEFORMATEX);
1343 LPVOID ptr;
1344 LPWAVEOPENDESC16 wod16;
1345
1346 /* allocated data are mapped as follows:
1347 LPWAVEOPENDESC ptr to orig lParam1
1348 DWORD ptr to orig dwUser, which is a pointer to DWORD:driver dwInstance
1349 DWORD dwUser passed to driver
1350 WAVEOPENDESC16 wod16: openDesc passed to driver
1351 WAVEFORMATEX openDesc->lpFormat passed to driver
1352 xxx extra bytes to WAVEFORMATEX
1353 */
1354 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1355 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1356 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1357 }
1358
1359 ptr = SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1360
1361 if (ptr) {
1362 *(LPWAVEOPENDESC*)ptr = wod32;
1363 *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1364 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1365
1366 wod16->hWave = wod32->hWave;
1367 wod16->lpFormat = (LPWAVEFORMATEX)((DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1368 memcpy(wod16 + 1, wod32->lpFormat, sz);
1369
1370 wod16->dwCallback = wod32->dwCallback;
1371 wod16->dwInstance = wod32->dwInstance;
1372 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1373 wod16->dnDevNode = wod32->dnDevNode;
1374
1375 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1376 *lpdwUser = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1377
1378 ret = MMDRV_MAP_OKMEM;
1379 } else {
1380 ret = MMDRV_MAP_NOMEM;
1381 }
1382 }
1383 break;
1384 case WODM_PREPARE:
1385 {
1386 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1387 LPWAVEHDR wh16;
1388 LPVOID ptr = SEGPTR_ALLOC(sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1389
1390 if (ptr) {
1391 *(LPWAVEHDR*)ptr = wh32;
1392 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1393 wh16->lpData = (LPSTR)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1394 /* data will be copied on WODM_WRITE */
1395 wh16->dwBufferLength = wh32->dwBufferLength;
1396 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1397 wh16->dwUser = wh32->dwUser;
1398 wh16->dwFlags = wh32->dwFlags;
1399 wh16->dwLoops = wh32->dwLoops;
1400 /* FIXME: nothing on wh32->lpNext */
1401 /* could link the wh32->lpNext at this level for memory house keeping */
1402 wh32->lpNext = wh16; /* for reuse in unprepare and write */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001403 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1404 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1405 wh32->dwBufferLength, (DWORD)wh32->lpData);
1406 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
1407 *lpParam2 = sizeof(WAVEHDR);
1408
1409 ret = MMDRV_MAP_OKMEM;
1410 } else {
1411 ret = MMDRV_MAP_NOMEM;
1412 }
1413 }
1414 break;
1415 case WODM_UNPREPARE:
1416 case WODM_WRITE:
1417 {
1418 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1419 LPWAVEHDR wh16 = wh32->lpNext;
1420 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1421
1422 assert(*(LPWAVEHDR*)ptr == wh32);
1423
1424 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1425 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1426 wh32->dwBufferLength, (DWORD)wh32->lpData);
1427
1428 if (wMsg == WODM_WRITE)
1429 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1430
1431 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
1432 *lpParam2 = sizeof(WAVEHDR);
1433 ret = MMDRV_MAP_OKMEM;
1434 }
1435 break;
1436 default:
1437 FIXME("NIY: no conversion yet\n");
1438 ret = MMDRV_MAP_MSGERROR;
1439 break;
1440 }
1441 return ret;
1442}
1443
1444/**************************************************************************
1445 * MMDRV_WaveOut_UnMap32ATo16 [internal]
1446 */
1447static MMDRV_MapType MMDRV_WaveOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1448{
1449 MMDRV_MapType ret;
1450
1451 switch (wMsg) {
1452 /* nothing to do */
1453 case WODM_BREAKLOOP:
1454 case WODM_CLOSE:
1455 case WODM_GETNUMDEVS:
1456 case WODM_PAUSE:
1457 case WODM_RESET:
1458 case WODM_RESTART:
1459 case WODM_SETPITCH:
1460 case WODM_SETPLAYBACKRATE:
1461 case WODM_SETVOLUME:
1462 ret = MMDRV_MAP_OK;
1463 break;
1464
1465 case WODM_GETDEVCAPS:
1466 {
1467 LPWAVEOUTCAPS16 woc16 = (LPWAVEOUTCAPS16)PTR_SEG_TO_LIN(*lpParam1);
1468 LPSTR ptr = (LPSTR)woc16 - sizeof(LPWAVEOUTCAPSA);
1469 LPWAVEOUTCAPSA woc32 = *(LPWAVEOUTCAPSA*)ptr;
1470
1471 woc32->wMid = woc16->wMid;
1472 woc32->wPid = woc16->wPid;
1473 woc32->vDriverVersion = woc16->vDriverVersion;
1474 strcpy(woc32->szPname, woc16->szPname);
1475 woc32->dwFormats = woc16->dwFormats;
1476 woc32->wChannels = woc16->wChannels;
1477 woc32->dwSupport = woc16->dwSupport;
1478 if (!SEGPTR_FREE(ptr))
1479 FIXME("bad free line=%d\n", __LINE__);
1480 ret = MMDRV_MAP_OK;
1481 }
1482 break;
1483 case WODM_GETPITCH:
1484 FIXME("NIY: no conversion yet\n");
1485 ret = MMDRV_MAP_MSGERROR;
1486 break;
1487 case WODM_GETPLAYBACKRATE:
1488 FIXME("NIY: no conversion yet\n");
1489 ret = MMDRV_MAP_MSGERROR;
1490 break;
1491 case WODM_GETPOS:
1492 {
1493 LPMMTIME16 mmt16 = (LPMMTIME16)PTR_SEG_TO_LIN(*lpParam1);
1494 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1495 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1496
1497 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1498
1499 if (!SEGPTR_FREE(ptr))
1500 FIXME("bad free line=%d\n", __LINE__);
1501
1502 ret = MMDRV_MAP_OK;
1503 }
1504 break;
1505 case WODM_OPEN:
1506 {
1507 LPWAVEOPENDESC16 wod16 = (LPWAVEOPENDESC16)PTR_SEG_TO_LIN(*lpParam1);
1508 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1509 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1510
1511 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1512 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1513
1514 if (!SEGPTR_FREE(ptr))
1515 FIXME("bad free line=%d\n", __LINE__);
1516
1517 ret = MMDRV_MAP_OK;
1518 }
1519 break;
1520 case WODM_PREPARE:
1521 case WODM_UNPREPARE:
1522 case WODM_WRITE:
1523 {
1524 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(*lpParam1);
1525 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1526 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1527
1528 assert(wh32->lpNext == wh16);
1529 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1530 wh32->dwUser = wh16->dwUser;
1531 wh32->dwFlags = wh16->dwFlags;
1532 wh32->dwLoops = wh16->dwLoops;
1533
1534 if (wMsg == WODM_UNPREPARE) {
1535 if (!SEGPTR_FREE(ptr))
1536 FIXME("bad free line=%d\n", __LINE__);
1537 wh32->lpNext = 0;
1538 }
1539 ret = MMDRV_MAP_OK;
1540 }
1541 break;
1542 case WODM_GETVOLUME:
1543 FIXME("NIY: no conversion yet\n");
1544 ret = MMDRV_MAP_MSGERROR;
1545 break;
1546 default:
1547 FIXME("NIY: no conversion yet\n");
1548 ret = MMDRV_MAP_MSGERROR;
1549 break;
1550 }
1551 return ret;
1552}
1553
1554/**************************************************************************
1555 * MMDRV_WaveOut_Callback [internal]
1556 */
1557static void CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1558{
1559 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1560
1561 switch (uMsg) {
1562 case WOM_OPEN:
1563 case WOM_CLOSE:
1564 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1565 break;
1566 case WOM_DONE:
1567 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1568 /* initial map is: 32 => 16 */
1569 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1);
1570 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1571
1572 dwParam1 = (DWORD)wh32;
1573 wh32->dwFlags = wh16->dwFlags;
1574 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1575 /* initial map is: 16 => 32 */
1576 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1577 LPWAVEHDR segwh16 = *(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1578 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(segwh16);
1579
1580 dwParam1 = (DWORD)segwh16;
1581 wh16->dwFlags = wh32->dwFlags;
1582 }
1583 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1584 break;
1585 default:
1586 ERR("Unknown msg %u\n", uMsg);
1587 }
1588
1589 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1590}
1591
1592#define A(_x,_y) {#_y, _x, \
1593MMDRV_##_y##_Map16To32A, MMDRV_##_y##_UnMap16To32A, \
1594MMDRV_##_y##_Map32ATo16, MMDRV_##_y##_UnMap32ATo16, \
1595MMDRV_##_y##_Callback, 0, NULL, -1}
1596
1597/* Note: the indices of this array must match the definitions
1598 * of the MMDRV_???? manifest constants
1599 */
1600static WINE_LLTYPE llTypes[MMDRV_MAX] = {
1601 A(TRUE, Aux),
1602 A(FALSE, Mixer),
1603 A(TRUE, MidiIn),
1604 A(TRUE, MidiOut),
1605 A(TRUE, WaveIn),
1606 A(TRUE, WaveOut),
1607};
1608#undef A
1609
1610/**************************************************************************
1611 * MMDRV_GetNum [internal]
1612 */
1613UINT MMDRV_GetNum(UINT type)
1614{
1615 assert(type < MMDRV_MAX);
1616 return llTypes[type].wMaxId;
1617}
1618
1619/**************************************************************************
1620 * WINE_Message [internal]
1621 */
1622DWORD MMDRV_Message(LPWINE_MLD mld, WORD wMsg, DWORD dwParam1,
1623 DWORD dwParam2, BOOL bFrom32)
1624{
1625 LPWINE_MM_DRIVER lpDrv;
1626 DWORD ret;
1627 WINE_MM_DRIVER_PART* part;
1628 WINE_LLTYPE* llType = &llTypes[mld->type];
1629 MMDRV_MapType map;
1630 int devID;
1631
1632 TRACE("(%s %u %u 0x%08lx 0x%08lx 0x%08lx %c)!\n",
1633 llTypes[mld->type].name, mld->uDeviceID, wMsg,
1634 mld->dwDriverInstance, dwParam1, dwParam2, bFrom32?'Y':'N');
1635
1636 if (mld->uDeviceID == (UINT16)-1) {
1637 if (!llType->bSupportMapper) {
1638 WARN("uDev=-1 requested on non-mappable ll type %s\n",
1639 llTypes[mld->type].name);
1640 return MMSYSERR_BADDEVICEID;
1641 }
1642 devID = -1;
1643 } else {
1644 if (mld->uDeviceID >= llType->wMaxId) {
1645 WARN("uDev(%u) requested >= max (%d)\n", mld->uDeviceID, llType->wMaxId);
1646 return MMSYSERR_BADDEVICEID;
1647 }
1648 devID = mld->uDeviceID;
1649 }
1650
1651 lpDrv = &MMDrvs[mld->mmdIndex];
1652 part = &lpDrv->parts[mld->type];
1653
1654#if 0
1655 /* some sanity checks */
1656 if (!(part->nIDMin <= devID))
1657 ERR("!(part->nIDMin(%d) <= devID(%d))\n", part->nIDMin, devID);
1658 if (!(devID < part->nIDMax))
1659 ERR("!(devID(%d) < part->nIDMax(%d))\n", devID, part->nIDMax);
1660#endif
1661
1662 if (lpDrv->bIs32) {
1663 assert(part->u.fnMessage32);
1664
1665 if (bFrom32) {
1666 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1667 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1668 ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1669 TRACE("=> %lu\n", ret);
1670 } else {
1671 map = llType->Map16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1672 switch (map) {
1673 case MMDRV_MAP_NOMEM:
1674 ret = MMSYSERR_NOMEM;
1675 break;
1676 case MMDRV_MAP_MSGERROR:
1677 FIXME("NIY: no conversion yet 16->32 (%u)\n", wMsg);
1678 ret = MMSYSERR_ERROR;
1679 break;
1680 case MMDRV_MAP_OK:
1681 case MMDRV_MAP_OKMEM:
1682 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1683 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1684 ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance,
1685 dwParam1, dwParam2);
1686 TRACE("=> %lu\n", ret);
1687 if (map == MMDRV_MAP_OKMEM)
1688 llType->UnMap16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1689 break;
1690 default:
1691 case MMDRV_MAP_PASS:
1692 FIXME("NIY: pass used ?\n");
1693 ret = MMSYSERR_NOTSUPPORTED;
1694 break;
1695 }
1696 }
1697 } else {
1698 assert(part->u.fnMessage16);
1699
1700 if (bFrom32) {
1701 map = llType->Map32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1702 switch (map) {
1703 case MMDRV_MAP_NOMEM:
1704 ret = MMSYSERR_NOMEM;
1705 break;
1706 case MMDRV_MAP_MSGERROR:
1707 FIXME("NIY: no conversion yet 32->16 (%u)\n", wMsg);
1708 ret = MMSYSERR_ERROR;
1709 break;
1710 case MMDRV_MAP_OK:
1711 case MMDRV_MAP_OKMEM:
1712 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1713 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1714 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
1715 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1716 TRACE("=> %lu\n", ret);
1717 if (map == MMDRV_MAP_OKMEM)
1718 llType->UnMap32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1719 break;
1720 default:
1721 case MMDRV_MAP_PASS:
1722 FIXME("NIY: pass used ?\n");
1723 ret = MMSYSERR_NOTSUPPORTED;
1724 break;
1725 }
1726 } else {
1727 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1728 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1729 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
1730 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1731 TRACE("=> %lu\n", ret);
1732 }
1733 }
1734 return ret;
1735}
1736
1737/**************************************************************************
1738 * MMDRV_Alloc [internal]
1739 */
1740LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
1741 DWORD* dwCallback, DWORD* dwInstance, BOOL bFrom32)
1742{
1743 LPWINE_MLD mld;
1744
1745 if ((*hndl = USER_HEAP_ALLOC(size)) == 0)
1746 return NULL;
1747
1748 mld = (LPWINE_MLD) USER_HEAP_LIN_ADDR(*hndl);
1749 if (!mld) return NULL;
1750 mld->type = type;
1751 if ((UINT)*hndl < MMDRV_GetNum(type) || HIWORD(*hndl) != 0) {
1752 /* FIXME: those conditions must be fulfilled so that:
1753 * - we can distinguish between device IDs and handles
1754 * - we can use handles as 16 or 32 bit entities
1755 */
1756 ERR("Shouldn't happen. Bad allocation scheme\n");
1757 }
1758
1759 mld->bFrom32 = bFrom32;
1760 mld->dwFlags = HIWORD(*dwFlags);
1761 mld->dwCallback = *dwCallback;
1762 mld->dwClientInstance = *dwInstance;
1763
1764 *dwFlags = LOWORD(*dwFlags) | CALLBACK_FUNCTION;
1765 *dwCallback = (DWORD)llTypes[type].Callback;
1766 *dwInstance = (DWORD)mld; /* FIXME: wouldn't some 16 bit drivers only use the loword ? */
1767
1768 return mld;
1769}
1770
1771/**************************************************************************
1772 * MMDRV_Free [internal]
1773 */
1774void MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
1775{
1776 USER_HEAP_FREE(hndl);
1777}
1778
1779/**************************************************************************
1780 * MMDRV_Open [internal]
1781 */
1782DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwFlags)
1783{
1784 DWORD dwRet = MMSYSERR_BADDEVICEID;
1785 DWORD dwInstance;
1786 WINE_LLTYPE* llType = &llTypes[mld->type];
1787
1788 mld->dwDriverInstance = (DWORD)&dwInstance;
1789
1790 if (mld->uDeviceID == (UINT)-1) {
1791 TRACE("MAPPER mode requested !\n");
1792 /* check if mapper is supported by type */
1793 if (llType->bSupportMapper) {
1794 if (llType->nMapper == -1) {
1795 /* no driver for mapper has been loaded, try a dumb implementation */
1796 TRACE("No mapper loaded, doing it by hand\n");
1797 for (mld->uDeviceID = 0; mld->uDeviceID < llType->wMaxId; mld->uDeviceID++) {
1798 if ((dwRet = MMDRV_Open(mld, wMsg, dwParam1, dwFlags)) == MMSYSERR_NOERROR) {
1799 /* to share this function epilog */
1800 dwInstance = mld->dwDriverInstance;
1801 break;
1802 }
1803 }
1804 } else {
Eric Pouech31a19331999-11-21 00:51:05 +00001805 mld->uDeviceID = (UINT16)-1;
Eric Pouech4853b6d1999-09-22 16:52:47 +00001806 mld->mmdIndex = llType->lpMlds[-1].mmdIndex;
1807 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
1808 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
1809 }
1810 }
1811 } else {
1812 if (mld->uDeviceID < llType->wMaxId) {
1813 mld->mmdIndex = llType->lpMlds[mld->uDeviceID].mmdIndex;
1814 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
1815 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
1816 }
1817 }
1818 if (dwRet == MMSYSERR_NOERROR)
1819 mld->dwDriverInstance = dwInstance;
1820 return dwRet;
1821}
1822
1823/**************************************************************************
1824 * MMDRV_Close [internal]
1825 */
1826DWORD MMDRV_Close(LPWINE_MLD mld, UINT wMsg)
1827{
1828 return MMDRV_Message(mld, wMsg, 0L, 0L, TRUE);
1829}
1830
1831/**************************************************************************
Eric Pouech31a19331999-11-21 00:51:05 +00001832 * MMDRV_GetByID [internal]
Eric Pouech4853b6d1999-09-22 16:52:47 +00001833 */
1834LPWINE_MLD MMDRV_GetByID(UINT uDevID, UINT type)
1835{
Eric Pouech31a19331999-11-21 00:51:05 +00001836 if (uDevID < llTypes[type].wMaxId)
1837 return &llTypes[type].lpMlds[uDevID];
1838 if ((uDevID == (UINT16)-1 || uDevID == (UINT)-1) && llTypes[type].nMapper != -1)
1839 return &llTypes[type].lpMlds[-1];
1840 return NULL;
Eric Pouech4853b6d1999-09-22 16:52:47 +00001841}
1842
1843/**************************************************************************
1844 * MMDRV_Get [internal]
1845 */
1846LPWINE_MLD MMDRV_Get(HANDLE hndl, UINT type, BOOL bCanBeID)
1847{
1848 LPWINE_MLD mld = NULL;
1849
1850 assert(type < MMDRV_MAX);
1851
1852 if ((UINT)hndl >= llTypes[type].wMaxId) {
1853 mld = (LPWINE_MLD)USER_HEAP_LIN_ADDR(hndl);
1854
Eric Pouech31a19331999-11-21 00:51:05 +00001855 if (!IsBadWritePtr(mld, sizeof(*mld)) && mld->type != type) mld = NULL;
1856 }
1857 if (mld == NULL && bCanBeID) {
Eric Pouech4853b6d1999-09-22 16:52:47 +00001858 mld = MMDRV_GetByID((UINT)hndl, type);
1859 }
1860 return mld;
1861}
1862
1863/**************************************************************************
1864 * MMDRV_GetRelated [internal]
1865 */
1866LPWINE_MLD MMDRV_GetRelated(HANDLE hndl, UINT srcType,
1867 BOOL bSrcCanBeID, UINT dstType)
1868{
1869 LPWINE_MLD mld;
1870
1871 if ((mld = MMDRV_Get(hndl, srcType, bSrcCanBeID)) != NULL) {
1872 WINE_MM_DRIVER_PART* part = &MMDrvs[mld->mmdIndex].parts[dstType];
1873 if (part->nIDMin < part->nIDMax)
1874 return MMDRV_GetByID(part->nIDMin, dstType);
1875 }
1876 return NULL;
1877}
1878
1879/**************************************************************************
1880 * MMDRV_PhysicalFeatures [internal]
1881 */
1882UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1,
1883 DWORD dwParam2)
1884{
1885 WINE_MM_DRIVER* lpDrv = &MMDrvs[mld->mmdIndex];
1886
1887 TRACE("(%p, %04x, %08lx, %08lx)\n", mld, uMsg, dwParam1, dwParam2);
1888
1889 /* all those function calls are undocumented */
1890 switch (uMsg) {
Eric Pouech31a19331999-11-21 00:51:05 +00001891 case 0x801: /* DRV_QUERYDRVENTRY */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001892 strncpy((LPSTR)dwParam1, lpDrv->name, LOWORD(dwParam2));
1893 break;
Eric Pouech31a19331999-11-21 00:51:05 +00001894 case 0x802: /* DRV_QUERYDEVNODE */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001895 *(LPDWORD)dwParam1 = 0L; /* should be DevNode */
1896 break;
Eric Pouech31a19331999-11-21 00:51:05 +00001897 case 0x803: /* DRV_QUERYNAME */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001898 WARN("NIY 0x803\n");
1899 break;
Eric Pouech31a19331999-11-21 00:51:05 +00001900 case 0x804: /* DRV_QUERYDRIVERIDS */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001901 WARN("NIY call VxD\n");
1902 /* should call VxD MMDEVLDR with (DevNode, dwParam1 and dwParam2) as pmts
1903 * dwParam1 is buffer and dwParam2 is sizeof buffer
1904 * I don't know where the result is stored though
1905 */
1906 break;
Eric Pouech31a19331999-11-21 00:51:05 +00001907 case 0x805: /* DRV_QUERYMAPPABLE */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001908 return (lpDrv->bIsMapper) ? 2 : 0;
1909 default:
1910 WARN("Unknown call %04x\n", uMsg);
1911 return MMSYSERR_INVALPARAM;
1912 }
1913 return 0L;
1914}
1915
1916/**************************************************************************
1917 * MMDRV_InitPerType [internal]
1918 */
Eric Pouech31655a61999-09-27 13:34:21 +00001919static BOOL MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv, UINT num,
Eric Pouech4853b6d1999-09-22 16:52:47 +00001920 UINT type, UINT wMsg)
1921{
1922 WINE_MM_DRIVER_PART* part = &lpDrv->parts[type];
Eric Pouech31655a61999-09-27 13:34:21 +00001923 DWORD ret;
1924 UINT count = 0;
1925 int i, k;
Eric Pouech4853b6d1999-09-22 16:52:47 +00001926
1927 part->nIDMin = part->nIDMax = 0;
1928
1929 /* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
1930 /* the DRVM_ENABLE is only required when the PnP node is non zero */
1931
1932 if (lpDrv->bIs32 && part->u.fnMessage32) {
1933 ret = part->u.fnMessage32(0, DRVM_INIT, 0L, 0L, 0L);
1934 TRACE("DRVM_INIT => %08lx\n", ret);
1935#if 0
1936 ret = part->u.fnMessage32(0, DRVM_ENABLE, 0L, 0L, 0L);
1937 TRACE("DRVM_ENABLE => %08lx\n", ret);
1938#endif
1939 count = part->u.fnMessage32(0, wMsg, 0L, 0L, 0L);
1940 }
1941
1942 if (!lpDrv->bIs32 && part->u.fnMessage16) {
1943 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
1944 0, DRVM_INIT, 0L, 0L, 0L);
1945 TRACE("DRVM_INIT => %08lx\n", ret);
1946#if 0
1947 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
1948 0, DRVM_ENABLE, 0L, 0L, 0L);
1949 TRACE("DRVM_ENABLE => %08lx\n", ret);
1950#endif
1951 count = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
1952 0, wMsg, 0L, 0L, 0L);
1953 }
1954
1955 TRACE("Got %u dev for (%s:%s)\n", count, lpDrv->name, llTypes[type].name);
Eric Pouech31655a61999-09-27 13:34:21 +00001956 if (count == 0)
1957 return FALSE;
1958
1959 /* got some drivers */
1960 if (lpDrv->bIsMapper) {
1961 if (llTypes[type].nMapper != -1)
1962 ERR("Two mappers for type %s (%d, %s)\n",
1963 llTypes[type].name, llTypes[type].nMapper, lpDrv->name);
1964 if (count > 1)
1965 ERR("Strange: mapper with %d > 1 devices\n", count);
1966 llTypes[type].nMapper = num;
1967 } else {
1968 part->nIDMin = llTypes[type].wMaxId;
1969 llTypes[type].wMaxId += count;
1970 part->nIDMax = llTypes[type].wMaxId;
Eric Pouech4853b6d1999-09-22 16:52:47 +00001971 }
Eric Pouech31655a61999-09-27 13:34:21 +00001972 TRACE("Setting min=%d max=%d (ttop=%d) for (%s:%s)\n",
1973 part->nIDMin, part->nIDMax, llTypes[type].wMaxId,
1974 lpDrv->name, llTypes[type].name);
1975 /* realloc translation table */
1976 llTypes[type].lpMlds = (LPWINE_MLD)
1977 HeapReAlloc(SystemHeap, 0, (llTypes[type].lpMlds) ? llTypes[type].lpMlds - 1 : NULL,
1978 sizeof(WINE_MLD) * (llTypes[type].wMaxId + 1)) + 1;
1979 /* re-build the translation table */
1980 if (llTypes[type].nMapper != -1) {
1981 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].name, -1, MMDrvs[llTypes[type].nMapper].name);
Eric Pouech31a19331999-11-21 00:51:05 +00001982 llTypes[type].lpMlds[-1].uDeviceID = (UINT16)-1;
Eric Pouech31655a61999-09-27 13:34:21 +00001983 llTypes[type].lpMlds[-1].type = type;
1984 llTypes[type].lpMlds[-1].mmdIndex = llTypes[type].nMapper;
1985 llTypes[type].lpMlds[-1].dwDriverInstance = 0;
1986 }
1987 for (i = k = 0; i <= num; i++) {
1988 while (MMDrvs[i].parts[type].nIDMin <= k && k < MMDrvs[i].parts[type].nIDMax) {
1989 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].name, k, MMDrvs[i].name);
1990 llTypes[type].lpMlds[k].uDeviceID = k;
1991 llTypes[type].lpMlds[k].type = type;
1992 llTypes[type].lpMlds[k].mmdIndex = i;
1993 llTypes[type].lpMlds[k].dwDriverInstance = 0;
1994 k++;
1995 }
1996 }
1997 return TRUE;
Eric Pouech4853b6d1999-09-22 16:52:47 +00001998}
1999
2000/**************************************************************************
2001 * MMDRV_Install [internal]
2002 */
2003static BOOL MMDRV_Install(LPCSTR name, int num, BOOL bIsMapper)
2004{
2005 int count = 0;
2006 char buffer[128];
2007 HMODULE hModule;
2008 LPWINE_MM_DRIVER lpDrv = &MMDrvs[num];
Eric Pouech4853b6d1999-09-22 16:52:47 +00002009
2010 TRACE("('%s');\n", name);
2011
2012 memset(lpDrv, 0, sizeof(*lpDrv));
2013
2014 /* First load driver */
2015 if ((lpDrv->hDrvr = OpenDriverA(name, 0, 0)) == 0) {
2016 WARN("Couldn't open driver '%s'\n", name);
2017 return FALSE;
2018 }
2019
2020 /* Then look for xxxMessage functions */
2021#define AA(_w,_x,_y,_z) \
2022 func = (WINEMM_msgFunc##_y) _z (hModule, #_x); \
2023 if (func != NULL) \
2024 { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
2025 TRACE("Got %d bit func '%s'\n", _y, #_x); }
2026
2027 if ((DRIVER_GetType(lpDrv->hDrvr) & WINE_DI_TYPE_MASK) == WINE_DI_TYPE_32) {
2028 WINEMM_msgFunc32 func;
2029
2030 lpDrv->bIs32 = TRUE;
2031 if ((hModule = GetDriverModuleHandle(lpDrv->hDrvr))) {
2032#define A(_x,_y) AA(_x,_y,32,GetProcAddress)
2033 A(MMDRV_AUX, auxMessage);
2034 A(MMDRV_MIXER, mixMessage);
2035 A(MMDRV_MIDIIN, midMessage);
2036 A(MMDRV_MIDIOUT, modMessage);
2037 A(MMDRV_WAVEIN, widMessage);
2038 A(MMDRV_WAVEOUT, wodMessage);
2039#undef A
2040 }
2041 } else {
2042 WINEMM_msgFunc16 func;
2043
2044 /*
2045 * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
2046 * The beginning of the module description indicates the driver supports
2047 * waveform, auxiliary, and mixer devices. Use one of the following
2048 * device-type names, followed by a colon (:) to indicate the type of
2049 * device your driver supports. If the driver supports more than one
2050 * type of device, separate each device-type name with a comma (,).
2051 *
2052 * wave for waveform audio devices
2053 * wavemapper for wave mappers
2054 * midi for MIDI audio devices
2055 * midimapper for midi mappers
2056 * aux for auxiliary audio devices
2057 * mixer for mixer devices
2058 */
2059
2060 lpDrv->bIs32 = FALSE;
2061 if ((hModule = GetDriverModuleHandle16(lpDrv->hDrvr))) {
2062#define A(_x,_y) AA(_x,_y,16,WIN32_GetProcAddress16)
2063 A(MMDRV_AUX, auxMessage);
2064 A(MMDRV_MIXER, mixMessage);
2065 A(MMDRV_MIDIIN, midMessage);
2066 A(MMDRV_MIDIOUT, modMessage);
2067 A(MMDRV_WAVEIN, widMessage);
2068 A(MMDRV_WAVEOUT, wodMessage);
2069#undef A
2070 }
2071 }
2072#undef AA
2073
2074 if (TRACE_ON(mmsys)) {
2075 if ((lpDrv->bIs32) ? MMDRV_GetDescription32(name, buffer, sizeof(buffer)) :
2076 MMDRV_GetDescription16(name, buffer, sizeof(buffer)))
2077 TRACE("%s => %s\n", name, buffer);
2078 else
2079 TRACE("%s => No description\n", name);
2080 }
2081
2082 if (!count) {
2083 CloseDriver(lpDrv->hDrvr, 0, 0);
2084 WARN("No message functions found\n");
2085 return FALSE;
2086 }
2087
2088 /* FIXME: being a mapper or not should be known by another way */
2089 /* it's known for NE drvs (the description is of the form '*mapper: *'
2090 * I don't have any clue for PE drvs
2091 * on Win 9x, the value is gotten from the key mappable under
2092 * HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\MediaResources\
2093 */
2094 lpDrv->bIsMapper = bIsMapper;
2095 lpDrv->name = HEAP_strdupA(GetProcessHeap(), 0, name);
2096
2097 /* Finish init and get the count of the devices */
2098 MMDRV_InitPerType(lpDrv, num, MMDRV_AUX, AUXDM_GETNUMDEVS);
2099 MMDRV_InitPerType(lpDrv, num, MMDRV_MIXER, MXDM_GETNUMDEVS);
2100 MMDRV_InitPerType(lpDrv, num, MMDRV_MIDIIN, MIDM_GETNUMDEVS);
2101 MMDRV_InitPerType(lpDrv, num, MMDRV_MIDIOUT, MODM_GETNUMDEVS);
2102 MMDRV_InitPerType(lpDrv, num, MMDRV_WAVEIN, WIDM_GETNUMDEVS);
2103 MMDRV_InitPerType(lpDrv, num, MMDRV_WAVEOUT, WODM_GETNUMDEVS);
Eric Pouech31655a61999-09-27 13:34:21 +00002104 /* FIXME: if all those func calls return FALSE, then the driver must be unloaded */
Eric Pouech4853b6d1999-09-22 16:52:47 +00002105 return TRUE;
2106}
2107
2108/**************************************************************************
2109 * MMDRV_Init [internal]
2110 */
2111BOOL MMDRV_Init(void)
2112{
2113 int num = 0;
2114
2115 /* FIXME: this should be moved to init files;
2116 * - either .winerc/wine.conf
2117 * - or made of registry keys
2118 * this is a temporary hack, shall be removed anytime now
2119 */
2120 /* first load hardware drivers */
2121 if (MMDRV_Install("wineoss.drv", num, FALSE)) num++;
2122
2123 /* finish with mappers */
2124 if (MMDRV_Install("msacm.drv", num, TRUE )) num++;
2125 if (MMDRV_Install("midimap.drv", num, TRUE )) num++;
2126
2127
2128 /* be sure that size of MMDrvs matches the max number of loadable drivers !!
2129 * if not just increase size of MMDrvs */
2130 assert(num <= sizeof(MMDrvs)/sizeof(MMDrvs[0]));
2131
2132 return TRUE;
2133}