blob: 0d19c9cc7351478273557676e71ff0cb9853d8ca [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
Eric Pouech28237782000-01-04 01:04:48 +000054typedef MMDRV_MapType (*MMDRV_MAPFUNC)(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +000055
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"));
Francois Gouget6d77d3a2000-03-25 21:44:35 +0000104 buflen = min((BYTE)buf[0], buflen - 1);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000105 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;
Alexandre Julliard3d678af2000-01-26 02:36:43 +0000126 FARPROC pGetFileVersionInfoSizeA;
127 FARPROC pGetFileVersionInfoA;
128 FARPROC pVerQueryValueA;
129 HMODULE hmodule = 0;
Eric Pouech4853b6d1999-09-22 16:52:47 +0000130
131#define E(_x) do {TRACE _x;goto theEnd;} while(0)
132
133 if (OpenFile(fname, &ofs, OF_EXIST)==HFILE_ERROR) E(("Can't find file %s\n", fname));
134
Alexandre Julliard3d678af2000-01-26 02:36:43 +0000135 if (!(hmodule = LoadLibraryA( "version.dll" ))) goto theEnd;
136 if (!(pGetFileVersionInfoSizeA = GetProcAddress( hmodule, "GetFileVersionInfoSizeA" )))
137 goto theEnd;
138 if (!(pGetFileVersionInfoA = GetProcAddress( hmodule, "GetFileVersionInfoA" )))
139 goto theEnd;
140 if (!(pVerQueryValueA = GetProcAddress( hmodule, "pVerQueryValueA" )))
141 goto theEnd;
142
143 if (!(dw = pGetFileVersionInfoSizeA(ofs.szPathName, &h))) E(("Can't get FVIS\n"));
Eric Pouech4853b6d1999-09-22 16:52:47 +0000144 if (!(ptr = HeapAlloc(GetProcessHeap(), 0, dw))) E(("OOM\n"));
Alexandre Julliard3d678af2000-01-26 02:36:43 +0000145 if (!pGetFileVersionInfoA(ofs.szPathName, h, dw, ptr)) E(("Can't get FVI\n"));
Eric Pouech4853b6d1999-09-22 16:52:47 +0000146
Alexandre Julliard3d678af2000-01-26 02:36:43 +0000147#define A(_x) if (pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\" #_x, &val, &u)) \
Eric Pouech4853b6d1999-09-22 16:52:47 +0000148 TRACE(#_x " => %s\n", (LPSTR)val); else TRACE(#_x " @\n")
149
150 A(CompanyName);
151 A(FileDescription);
152 A(FileVersion);
153 A(InternalName);
154 A(LegalCopyright);
155 A(OriginalFilename);
156 A(ProductName);
157 A(ProductVersion);
158 A(Comments);
159 A(LegalTrademarks);
160 A(PrivateBuild);
161 A(SpecialBuild);
162#undef A
163
Alexandre Julliard3d678af2000-01-26 02:36:43 +0000164 if (!pVerQueryValueA(ptr, "\\StringFileInfo\\040904B0\\ProductName", &val, &u)) E(("Can't get product name\n"));
Francois Gougetbaa9bf91999-12-27 05:24:06 +0000165 lstrcpynA(buf, val, buflen);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000166
167#undef E
168 ret = TRUE;
169theEnd:
170 HeapFree(GetProcessHeap(), 0, ptr);
Alexandre Julliard3d678af2000-01-26 02:36:43 +0000171 if (hmodule) FreeLibrary( hmodule );
Eric Pouech4853b6d1999-09-22 16:52:47 +0000172 return ret;
173}
174
175/**************************************************************************
176 * MMDRV_Callback [internal]
177 */
178static void MMDRV_Callback(LPWINE_MLD mld, HDRVR hDev, UINT uMsg, DWORD dwParam1, DWORD dwParam2)
179{
180 TRACE("CB (*%08lx)(%08x %08x %08lx %08lx %08lx\n",
181 mld->dwCallback, hDev, uMsg, mld->dwClientInstance, dwParam1, dwParam2);
182
183 if (!mld->bFrom32 && (mld->dwFlags & DCB_TYPEMASK) == DCB_FUNCTION) {
184 /* 16 bit func, call it */
185 TRACE("Function (16 bit) !\n");
186 MMDRV_CallTo16_word_wwlll((FARPROC16)mld->dwCallback, hDev, uMsg,
187 mld->dwClientInstance, dwParam1, dwParam2);
188 } else {
189 DriverCallback(mld->dwCallback, mld->dwFlags, hDev, uMsg,
190 mld->dwClientInstance, dwParam1, dwParam2);
191 }
192}
193
194/* =================================
195 * A U X M A P P E R S
196 * ================================= */
197
198/**************************************************************************
199 * MMDRV_Aux_Map16To32A [internal]
200 */
201static MMDRV_MapType MMDRV_Aux_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
202{
203 return MMDRV_MAP_MSGERROR;
204}
205
206/**************************************************************************
207 * MMDRV_Aux_UnMap16To32A [internal]
208 */
209static MMDRV_MapType MMDRV_Aux_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
210{
211 return MMDRV_MAP_MSGERROR;
212}
213
214/**************************************************************************
215 * MMDRV_Aux_Map32ATo16 [internal]
216 */
217static MMDRV_MapType MMDRV_Aux_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
218{
219 return MMDRV_MAP_MSGERROR;
220}
221
222/**************************************************************************
223 * MMDRV_Aux_UnMap32ATo16 [internal]
224 */
225static MMDRV_MapType MMDRV_Aux_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
226{
227#if 0
228 case AUXDM_GETDEVCAPS:
229 lpCaps->wMid = ac16.wMid;
230 lpCaps->wPid = ac16.wPid;
231 lpCaps->vDriverVersion = ac16.vDriverVersion;
232 strcpy(lpCaps->szPname, ac16.szPname);
233 lpCaps->wTechnology = ac16.wTechnology;
234 lpCaps->dwSupport = ac16.dwSupport;
235#endif
236 return MMDRV_MAP_MSGERROR;
237}
238
239/**************************************************************************
240 * MMDRV_Aux_Callback [internal]
241 */
242static void CALLBACK MMDRV_Aux_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
243{
244 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
245
246 FIXME("NIY\n");
247 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
248}
249
250/* =================================
251 * M I X E R M A P P E R S
252 * ================================= */
253
254/**************************************************************************
255 * xMMDRV_Mixer_Map16To32A [internal]
256 */
257static MMDRV_MapType MMDRV_Mixer_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
258{
259 return MMDRV_MAP_MSGERROR;
260}
261
262/**************************************************************************
263 * MMDRV_Mixer_UnMap16To32A [internal]
264 */
265static MMDRV_MapType MMDRV_Mixer_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
266{
267#if 0
268 MIXERCAPSA micA;
269 UINT ret = mixerGetDevCapsA(devid, &micA, sizeof(micA));
270
271 if (ret == MMSYSERR_NOERROR) {
272 mixcaps->wMid = micA.wMid;
273 mixcaps->wPid = micA.wPid;
274 mixcaps->vDriverVersion = micA.vDriverVersion;
275 strcpy(mixcaps->szPname, micA.szPname);
276 mixcaps->fdwSupport = micA.fdwSupport;
277 mixcaps->cDestinations = micA.cDestinations;
278 }
279 return ret;
280#endif
281 return MMDRV_MAP_MSGERROR;
282}
283
284/**************************************************************************
285 * MMDRV_Mixer_Map32ATo16 [internal]
286 */
287static MMDRV_MapType MMDRV_Mixer_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
288{
289 return MMDRV_MAP_MSGERROR;
290}
291
292/**************************************************************************
293 * MMDRV_Mixer_UnMap32ATo16 [internal]
294 */
295static MMDRV_MapType MMDRV_Mixer_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
296{
297 return MMDRV_MAP_MSGERROR;
298}
299
300/**************************************************************************
301 * MMDRV_Mixer_Callback [internal]
302 */
303static void CALLBACK MMDRV_Mixer_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
304{
305 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
306
307 FIXME("NIY\n");
308 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
309}
310
311/* =================================
312 * M I D I I N M A P P E R S
313 * ================================= */
314
315/**************************************************************************
316 * MMDRV_MidiIn_Map16To32A [internal]
317 */
318static MMDRV_MapType MMDRV_MidiIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
319{
320 return MMDRV_MAP_MSGERROR;
321}
322
323/**************************************************************************
324 * MMDRV_MidiIn_UnMap16To32A [internal]
325 */
326static MMDRV_MapType MMDRV_MidiIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
327{
328 return MMDRV_MAP_MSGERROR;
329}
330
331/**************************************************************************
332 * MMDRV_MidiIn_Map32ATo16 [internal]
333 */
334static MMDRV_MapType MMDRV_MidiIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
335{
336 return MMDRV_MAP_MSGERROR;
337}
338
339/**************************************************************************
340 * MMDRV_MidiIn_UnMap32ATo16 [internal]
341 */
342static MMDRV_MapType MMDRV_MidiIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
343{
344 return MMDRV_MAP_MSGERROR;
345}
346
347/**************************************************************************
348 * MMDRV_MidiIn_Callback [internal]
349 */
350static void CALLBACK MMDRV_MidiIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
351{
352 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
353
Eric Pouechaa5f5a31999-12-05 02:17:40 +0000354 switch (uMsg) {
355 case MIM_OPEN:
356 case MIM_CLOSE:
357 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
358
359 case MIM_DATA:
360 case MIM_MOREDATA:
361 case MIM_ERROR:
362 /* dwParam1 & dwParam2 are are data, nothing to do */
363 break;
364 case MIM_LONGDATA:
365 case MIM_LONGERROR:
366 /* dwParam1 points to a MidiHdr, work to be done !!! */
367 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
368 /* initial map is: 32 => 16 */
Eric Pouech28237782000-01-04 01:04:48 +0000369 LPMIDIHDR mh16 = (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1);
370 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
Eric Pouechaa5f5a31999-12-05 02:17:40 +0000371
Eric Pouech28237782000-01-04 01:04:48 +0000372 dwParam1 = (DWORD)mh32;
373 mh32->dwFlags = mh16->dwFlags;
374 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
375 if (mh32->reserved >= sizeof(MIDIHDR))
376 mh32->dwOffset = mh16->dwOffset;
Eric Pouechaa5f5a31999-12-05 02:17:40 +0000377 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
378 /* initial map is: 16 => 32 */
Eric Pouech28237782000-01-04 01:04:48 +0000379 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
380 LPMIDIHDR segmh16 = *(LPMIDIHDR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
381 LPMIDIHDR mh16 = PTR_SEG_TO_LIN(segmh16);
Eric Pouechaa5f5a31999-12-05 02:17:40 +0000382
Eric Pouech28237782000-01-04 01:04:48 +0000383 dwParam1 = (DWORD)segmh16;
384 mh16->dwFlags = mh32->dwFlags;
385 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
386 if (mh16->reserved >= sizeof(MIDIHDR))
387 mh16->dwOffset = mh32->dwOffset;
Eric Pouechaa5f5a31999-12-05 02:17:40 +0000388 }
389 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
390 break;
391 /* case MOM_POSITIONCB: */
392 default:
393 ERR("Unknown msg %u\n", uMsg);
394 }
395
Eric Pouech4853b6d1999-09-22 16:52:47 +0000396 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
397}
398
399/* =================================
400 * M I D I O U T M A P P E R S
401 * ================================= */
402
403/**************************************************************************
404 * MMDRV_MidiOut_Map16To32A [internal]
405 */
406static MMDRV_MapType MMDRV_MidiOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
407{
408 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
409
410 switch (wMsg) {
411 case MODM_GETNUMDEVS:
412 case MODM_DATA:
413 case MODM_RESET:
414 case MODM_SETVOLUME:
415 ret = MMDRV_MAP_OK;
416 break;
417
418 case MODM_OPEN:
419 case MODM_CLOSE:
Eric Pouech28237782000-01-04 01:04:48 +0000420 case MODM_GETVOLUME:
Eric Pouech4853b6d1999-09-22 16:52:47 +0000421 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
422 break;
423
424 case MODM_GETDEVCAPS:
425 {
426 LPMIDIOUTCAPSA moc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIOUTCAPS16) + sizeof(MIDIOUTCAPSA));
427 LPMIDIOUTCAPS16 moc16 = PTR_SEG_TO_LIN(*lpParam1);
428
429 if (moc32) {
430 *(LPMIDIOUTCAPS16*)moc32 = moc16;
431 moc32 = (LPMIDIOUTCAPSA)((LPSTR)moc32 + sizeof(LPMIDIOUTCAPS16));
432 *lpParam1 = (DWORD)moc32;
433 *lpParam2 = sizeof(MIDIOUTCAPSA);
434
435 ret = MMDRV_MAP_OKMEM;
436 } else {
437 ret = MMDRV_MAP_NOMEM;
438 }
439 }
440 break;
441 case MODM_PREPARE:
Eric Pouech28237782000-01-04 01:04:48 +0000442 {
443 LPMIDIHDR mh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMIDIHDR) + sizeof(MIDIHDR));
444 LPMIDIHDR mh16 = PTR_SEG_TO_LIN(*lpParam1);
445
446 if (mh32) {
447 *(LPMIDIHDR*)mh32 = (LPMIDIHDR)*lpParam1;
448 mh32 = (LPMIDIHDR)((LPSTR)mh32 + sizeof(LPMIDIHDR));
449 mh32->lpData = PTR_SEG_TO_LIN(mh16->lpData);
450 mh32->dwBufferLength = mh16->dwBufferLength;
451 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
452 mh32->dwUser = mh16->dwUser;
453 mh32->dwFlags = mh16->dwFlags;
454 /* FIXME: nothing on mh32->lpNext */
455 /* could link the mh32->lpNext at this level for memory house keeping */
456 mh32->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? ((LPMIDIHDR)mh16)->dwOffset : 0;
457 mh16->lpNext = mh32; /* for reuse in unprepare and write */
458 /* store size of passed MIDIHDR?? structure to know if dwOffset is available or not */
459 mh16->reserved = *lpParam2;
460 *lpParam1 = (DWORD)mh32;
461 *lpParam2 = sizeof(MIDIHDR);
462
463 ret = MMDRV_MAP_OKMEM;
464 } else {
465 ret = MMDRV_MAP_NOMEM;
466 }
467 }
468 break;
Eric Pouech4853b6d1999-09-22 16:52:47 +0000469 case MODM_UNPREPARE:
470 case MODM_LONGDATA:
Eric Pouech28237782000-01-04 01:04:48 +0000471 {
472 LPMIDIHDR mh16 = PTR_SEG_TO_LIN(*lpParam1);
473 LPMIDIHDR mh32 = (LPMIDIHDR)mh16->lpNext;
474
475 *lpParam1 = (DWORD)mh32;
476 *lpParam2 = sizeof(MIDIHDR);
477 /* dwBufferLength can be reduced between prepare & write */
478 if (mh32->dwBufferLength < mh16->dwBufferLength) {
479 ERR("Size of buffer has been increased (%ld, %ld)\n",
480 mh32->dwBufferLength, mh16->dwBufferLength);
481 return MMDRV_MAP_MSGERROR;
482 }
483 mh32->dwBufferLength = mh16->dwBufferLength;
484 ret = MMDRV_MAP_OKMEM;
485 }
486 break;
487
Eric Pouech4853b6d1999-09-22 16:52:47 +0000488 case MODM_CACHEPATCHES:
489 case MODM_CACHEDRUMPATCHES:
490 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000491 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000492 break;
493 }
494 return ret;
495}
496
497/**************************************************************************
498 * MMDRV_MidiOut_UnMap16To32A [internal]
499 */
500static MMDRV_MapType MMDRV_MidiOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
501{
502 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
503
504 switch (wMsg) {
505 case MODM_GETNUMDEVS:
506 case MODM_DATA:
507 case MODM_RESET:
508 case MODM_SETVOLUME:
509 ret = MMDRV_MAP_OK;
510 break;
511
512 case MODM_OPEN:
513 case MODM_CLOSE:
Eric Pouech28237782000-01-04 01:04:48 +0000514 case MODM_GETVOLUME:
Eric Pouech4853b6d1999-09-22 16:52:47 +0000515 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
516 break;
517
518 case MODM_GETDEVCAPS:
519 {
520 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)(*lpParam1);
521 LPMIDIOUTCAPS16 moc16 = *(LPMIDIOUTCAPS16*)((LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
522
523 moc16->wMid = moc32->wMid;
524 moc16->wPid = moc32->wPid;
525 moc16->vDriverVersion = moc32->vDriverVersion;
526 strcpy(moc16->szPname, moc32->szPname);
527 moc16->wTechnology = moc32->wTechnology;
528 moc16->wVoices = moc32->wVoices;
529 moc16->wNotes = moc32->wNotes;
530 moc16->wChannelMask = moc32->wChannelMask;
531 moc16->dwSupport = moc32->dwSupport;
532 HeapFree(GetProcessHeap(), 0, (LPSTR)moc32 - sizeof(LPMIDIOUTCAPS16));
533 ret = MMDRV_MAP_OK;
534 }
535 break;
536 case MODM_PREPARE:
537 case MODM_UNPREPARE:
538 case MODM_LONGDATA:
Eric Pouech28237782000-01-04 01:04:48 +0000539 {
540 LPMIDIHDR mh32 = (LPMIDIHDR)(*lpParam1);
541 LPMIDIHDR mh16 = PTR_SEG_TO_LIN(*(LPMIDIHDR*)((LPSTR)mh32 - sizeof(LPMIDIHDR)));
542
543 assert(mh16->lpNext == mh32);
544 mh16->dwBufferLength = mh32->dwBufferLength;
545 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
546 mh16->dwUser = mh32->dwUser;
547 mh16->dwFlags = mh32->dwFlags;
548 if (mh16->reserved >= sizeof(MIDIHDR))
549 mh16->dwOffset = mh32->dwOffset;
550
551 if (wMsg == MODM_UNPREPARE) {
552 HeapFree(GetProcessHeap(), 0, (LPSTR)mh32 - sizeof(LPMIDIHDR));
553 mh16->lpNext = 0;
554 }
555 ret = MMDRV_MAP_OK;
556 }
557 break;
558
Eric Pouech4853b6d1999-09-22 16:52:47 +0000559 case MODM_CACHEPATCHES:
560 case MODM_CACHEDRUMPATCHES:
561 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000562 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000563 break;
564 }
565 return ret;
566}
567
568/**************************************************************************
569 * MMDRV_MidiOut_Map32ATo16 [internal]
570 */
571static MMDRV_MapType MMDRV_MidiOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
572{
573 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
574
575 switch (wMsg) {
576 case MODM_CLOSE:
577 case MODM_GETNUMDEVS:
578 case MODM_DATA:
579 case MODM_RESET:
580 case MODM_SETVOLUME:
581 ret = MMDRV_MAP_OK;
582 break;
583 case MODM_GETDEVCAPS:
584 {
585 LPMIDIOUTCAPSA moc32 = (LPMIDIOUTCAPSA)*lpParam1;
586 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPMIDIOUTCAPSA) + sizeof(MIDIOUTCAPS16));
587
588 if (ptr) {
589 *(LPMIDIOUTCAPSA*)ptr = moc32;
590 ret = MMDRV_MAP_OKMEM;
591 } else {
592 ret = MMDRV_MAP_NOMEM;
593 }
594 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIOUTCAPSA);
595 *lpParam2 = sizeof(MIDIOUTCAPS16);
596 }
597 break;
Eric Pouech4853b6d1999-09-22 16:52:47 +0000598 case MODM_PREPARE:
Eric Pouech28237782000-01-04 01:04:48 +0000599 {
600 LPMIDIHDR mh32 = (LPMIDIHDR)*lpParam1;
601 LPMIDIHDR mh16;
602 LPVOID ptr = SEGPTR_ALLOC(sizeof(LPMIDIHDR) + sizeof(MIDIHDR) + mh32->dwBufferLength);
603
604 if (ptr) {
605 *(LPMIDIHDR*)ptr = mh32;
606 mh16 = (LPMIDIHDR)((LPSTR)ptr + sizeof(LPMIDIHDR));
607 mh16->lpData = (LPSTR)SEGPTR_GET(ptr) + sizeof(LPMIDIHDR) + sizeof(MIDIHDR);
608 /* data will be copied on WODM_WRITE */
609 mh16->dwBufferLength = mh32->dwBufferLength;
610 mh16->dwBytesRecorded = mh32->dwBytesRecorded;
611 mh16->dwUser = mh32->dwUser;
612 mh16->dwFlags = mh32->dwFlags;
613 /* FIXME: nothing on mh32->lpNext */
614 /* could link the mh32->lpNext at this level for memory house keeping */
615 mh16->dwOffset = (*lpParam2 >= sizeof(MIDIHDR)) ? mh32->dwOffset : 0;
616
617 mh32->lpNext = (LPMIDIHDR)mh16; /* for reuse in unprepare and write */
618 mh32->reserved = *lpParam2;
619
620 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
621 (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIHDR), (DWORD)mh16->lpData,
622 mh32->dwBufferLength, (DWORD)mh32->lpData);
623 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIHDR);
624 *lpParam2 = sizeof(MIDIHDR);
625
626 ret = MMDRV_MAP_OKMEM;
627 } else {
628 ret = MMDRV_MAP_NOMEM;
629 }
630 }
631 break;
Eric Pouech4853b6d1999-09-22 16:52:47 +0000632 case MODM_UNPREPARE:
633 case MODM_LONGDATA:
Eric Pouech28237782000-01-04 01:04:48 +0000634 {
635 LPMIDIHDR mh32 = (LPMIDIHDR)(*lpParam1);
636 LPMIDIHDR mh16 = (LPMIDIHDR)mh32->lpNext;
637 LPSTR ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
638
639 assert(*(LPMIDIHDR*)ptr == mh32);
640
641 TRACE("mh16=%08lx mh16->lpData=%08lx mh32->buflen=%lu mh32->lpData=%08lx\n",
642 (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIHDR), (DWORD)mh16->lpData,
643 mh32->dwBufferLength, (DWORD)mh32->lpData);
644
645 if (wMsg == MODM_LONGDATA)
646 memcpy((LPSTR)mh16 + sizeof(MIDIHDR), mh32->lpData, mh32->dwBufferLength);
647
648 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIHDR);
649 *lpParam2 = sizeof(MIDIHDR);
650 /* dwBufferLength can be reduced between prepare & write */
651 if (mh16->dwBufferLength < mh32->dwBufferLength) {
652 ERR("Size of buffer has been increased (%ld, %ld)\n",
653 mh16->dwBufferLength, mh32->dwBufferLength);
654 return MMDRV_MAP_MSGERROR;
655 }
656 mh16->dwBufferLength = mh32->dwBufferLength;
657 ret = MMDRV_MAP_OKMEM;
658 }
659 break;
660 case MODM_OPEN:
661 {
662 LPMIDIOPENDESC mod32 = (LPMIDIOPENDESC)*lpParam1;
663 LPVOID ptr;
664 LPMIDIOPENDESC16 mod16;
665
666 /* allocated data are mapped as follows:
667 LPMIDIOPENDESC ptr to orig lParam1
668 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
669 DWORD dwUser passed to driver
670 MIDIOPENDESC16 mod16: openDesc passed to driver
671 MIDIOPENSTRMID cIds
672 */
673 ptr = SEGPTR_ALLOC(sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD) + sizeof(MIDIOPENDESC16) +
674 mod32->cIds ? (mod32->cIds - 1) * sizeof(MIDIOPENSTRMID) : 0);
675
676 if (ptr) {
677 *(LPMIDIOPENDESC*)ptr = mod32;
678 *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC)) = *lpdwUser;
679 mod16 = (LPMIDIOPENDESC16)((LPSTR)ptr + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD));
680
681 mod16->hMidi = mod32->hMidi;
682 mod16->dwCallback = mod32->dwCallback;
683 mod16->dwInstance = mod32->dwInstance;
684 mod16->dnDevNode = mod32->dnDevNode;
685 mod16->cIds = mod32->cIds;
686 memcpy(&mod16->rgIds, &mod32->rgIds, mod32->cIds * sizeof(MIDIOPENSTRMID));
687
688 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIOPENDESC) + 2*sizeof(DWORD);
689 *lpdwUser = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMIDIOPENDESC) + sizeof(DWORD);
690
691 ret = MMDRV_MAP_OKMEM;
692 } else {
693 ret = MMDRV_MAP_NOMEM;
694 }
695 }
696 break;
Eric Pouech4853b6d1999-09-22 16:52:47 +0000697 case MODM_GETVOLUME:
698 case MODM_CACHEPATCHES:
699 case MODM_CACHEDRUMPATCHES:
700 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000701 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000702 break;
703 }
704 return ret;
705}
706
707/**************************************************************************
708 * MMDRV_MidiOut_UnMap32ATo16 [internal]
709 */
710static MMDRV_MapType MMDRV_MidiOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
711{
712 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
713
714 switch (wMsg) {
715 case MODM_CLOSE:
716 case MODM_GETNUMDEVS:
717 case MODM_DATA:
718 case MODM_RESET:
719 case MODM_SETVOLUME:
720 ret = MMDRV_MAP_OK;
721 break;
722 case MODM_GETDEVCAPS:
723 {
724 LPMIDIOUTCAPS16 moc16 = (LPMIDIOUTCAPS16)PTR_SEG_TO_LIN(*lpParam1);
725 LPSTR ptr = (LPSTR)moc16 - sizeof(LPMIDIOUTCAPSA);
726 LPMIDIOUTCAPSA moc32 = *(LPMIDIOUTCAPSA*)ptr;
727
728 moc32->wMid = moc16->wMid;
729 moc32->wPid = moc16->wPid;
730 moc32->vDriverVersion = moc16->vDriverVersion;
731 strcpy(moc32->szPname, moc16->szPname);
732 moc32->wTechnology = moc16->wTechnology;
733 moc32->wVoices = moc16->wVoices;
734 moc32->wNotes = moc16->wNotes;
735 moc32->wChannelMask = moc16->wChannelMask;
736 moc32->dwSupport = moc16->dwSupport;
737
738 if (!SEGPTR_FREE(ptr))
739 FIXME("bad free line=%d\n", __LINE__);
740 ret = MMDRV_MAP_OK;
741 }
742 break;
Eric Pouech4853b6d1999-09-22 16:52:47 +0000743 case MODM_PREPARE:
744 case MODM_UNPREPARE:
745 case MODM_LONGDATA:
Eric Pouech28237782000-01-04 01:04:48 +0000746 {
747 LPMIDIHDR mh16 = (LPMIDIHDR)PTR_SEG_TO_LIN(*lpParam1);
748 LPSTR ptr = (LPSTR)mh16 - sizeof(LPMIDIHDR);
749 LPMIDIHDR mh32 = *(LPMIDIHDR*)ptr;
750
751 assert(mh32->lpNext == (LPMIDIHDR)mh16);
752 mh32->dwBytesRecorded = mh16->dwBytesRecorded;
753 mh32->dwUser = mh16->dwUser;
754 mh32->dwFlags = mh16->dwFlags;
755
756 if (wMsg == MODM_UNPREPARE) {
757 if (!SEGPTR_FREE(ptr))
758 FIXME("bad free line=%d\n", __LINE__);
759 mh32->lpNext = 0;
760 }
761 ret = MMDRV_MAP_OK;
762 }
763 break;
764 case MODM_OPEN:
765 {
766 LPMIDIOPENDESC16 mod16 = (LPMIDIOPENDESC16)PTR_SEG_TO_LIN(*lpParam1);
767 LPSTR ptr = (LPSTR)mod16 - sizeof(LPMIDIOPENDESC) - 2*sizeof(DWORD);
768
769 **(DWORD**)(ptr + sizeof(LPMIDIOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPMIDIOPENDESC) + sizeof(DWORD));
770
771 if (!SEGPTR_FREE(ptr))
772 FIXME("bad free line=%d\n", __LINE__);
773
774 ret = MMDRV_MAP_OK;
775 }
776 break;
Eric Pouech4853b6d1999-09-22 16:52:47 +0000777 case MODM_GETVOLUME:
778 case MODM_CACHEPATCHES:
779 case MODM_CACHEDRUMPATCHES:
780 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000781 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000782 break;
783 }
784 return ret;
785}
786
787/**************************************************************************
788 * MMDRV_MidiOut_Callback [internal]
789 */
790static void CALLBACK MMDRV_MidiOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
791{
792 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
793
794 switch (uMsg) {
795 case MOM_OPEN:
796 case MOM_CLOSE:
797 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
798 break;
799 case MOM_DONE:
800 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
801 /* initial map is: 32 => 16 */
Eric Pouech28237782000-01-04 01:04:48 +0000802 LPMIDIHDR mh16 = (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1);
803 LPMIDIHDR mh32 = *(LPMIDIHDR*)((LPSTR)mh16 - sizeof(LPMIDIHDR));
Eric Pouech4853b6d1999-09-22 16:52:47 +0000804
Eric Pouech28237782000-01-04 01:04:48 +0000805 dwParam1 = (DWORD)mh32;
806 mh32->dwFlags = mh16->dwFlags;
807 mh32->dwOffset = mh16->dwOffset;
808 if (mh32->reserved >= sizeof(MIDIHDR))
809 mh32->dwOffset = mh16->dwOffset;
Eric Pouech4853b6d1999-09-22 16:52:47 +0000810 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
811 /* initial map is: 16 => 32 */
Eric Pouech28237782000-01-04 01:04:48 +0000812 LPMIDIHDR mh32 = (LPMIDIHDR)(dwParam1);
813 LPMIDIHDR segmh16 = *(LPMIDIHDR*)((LPSTR)mh32 - sizeof(LPMIDIHDR));
814 LPMIDIHDR mh16 = PTR_SEG_TO_LIN(segmh16);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000815
Eric Pouech28237782000-01-04 01:04:48 +0000816 dwParam1 = (DWORD)segmh16;
817 mh16->dwFlags = mh32->dwFlags;
818 if (mh16->reserved >= sizeof(MIDIHDR))
819 mh16->dwOffset = mh32->dwOffset;
Eric Pouech4853b6d1999-09-22 16:52:47 +0000820 }
821 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
822 break;
823 /* case MOM_POSITIONCB: */
824 default:
825 ERR("Unknown msg %u\n", uMsg);
826 }
827
828 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
829}
830
831/* =================================
832 * W A V E I N M A P P E R S
833 * ================================= */
834
835/**************************************************************************
836 * MMDRV_WaveIn_Map16To32A [internal]
837 */
838static MMDRV_MapType MMDRV_WaveIn_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
839{
840 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
841
842 switch (wMsg) {
843 case WIDM_GETNUMDEVS:
844 case WIDM_RESET:
845 case WIDM_START:
846 case WIDM_STOP:
847 ret = MMDRV_MAP_OK;
848 break;
849 case WIDM_OPEN:
850 case WIDM_CLOSE:
851 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
852 break;
853 case WIDM_GETDEVCAPS:
854 {
855 LPWAVEINCAPSA wic32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEINCAPS16) + sizeof(WAVEINCAPSA));
856 LPWAVEINCAPS16 wic16 = PTR_SEG_TO_LIN(*lpParam1);
857
858 if (wic32) {
859 *(LPWAVEINCAPS16*)wic32 = wic16;
860 wic32 = (LPWAVEINCAPSA)((LPSTR)wic32 + sizeof(LPWAVEINCAPS16));
861 *lpParam1 = (DWORD)wic32;
862 *lpParam2 = sizeof(WAVEINCAPSA);
863
864 ret = MMDRV_MAP_OKMEM;
865 } else {
866 ret = MMDRV_MAP_NOMEM;
867 }
868 }
869 break;
870 case WIDM_GETPOS:
871 {
872 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
873 LPMMTIME16 mmt16 = PTR_SEG_TO_LIN(*lpParam1);
874
875 if (mmt32) {
876 *(LPMMTIME16*)mmt32 = mmt16;
877 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
878
879 mmt32->wType = mmt16->wType;
880 *lpParam1 = (DWORD)mmt32;
881 *lpParam2 = sizeof(MMTIME);
882
883 ret = MMDRV_MAP_OKMEM;
884 } else {
885 ret = MMDRV_MAP_NOMEM;
886 }
887 }
888 break;
889 case WIDM_PREPARE:
890 {
891 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
892 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
893
894 if (wh32) {
895 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
896 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
897 wh32->lpData = PTR_SEG_TO_LIN(wh16->lpData);
898 wh32->dwBufferLength = wh16->dwBufferLength;
899 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
900 wh32->dwUser = wh16->dwUser;
901 wh32->dwFlags = wh16->dwFlags;
902 wh32->dwLoops = wh16->dwLoops;
903 /* FIXME: nothing on wh32->lpNext */
904 /* could link the wh32->lpNext at this level for memory house keeping */
905 wh16->lpNext = wh32; /* for reuse in unprepare and write */
Eric Pouech4853b6d1999-09-22 16:52:47 +0000906 *lpParam1 = (DWORD)wh32;
907 *lpParam2 = sizeof(WAVEHDR);
908
909 ret = MMDRV_MAP_OKMEM;
910 } else {
911 ret = MMDRV_MAP_NOMEM;
912 }
913 }
914 break;
915 case WIDM_ADDBUFFER:
916 case WIDM_UNPREPARE:
917 {
918 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
919 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
920
921 *lpParam1 = (DWORD)wh32;
922 *lpParam2 = sizeof(WAVEHDR);
Eric Pouech28237782000-01-04 01:04:48 +0000923 /* dwBufferLength can be reduced between prepare & write */
924 if (wh32->dwBufferLength < wh16->dwBufferLength) {
925 ERR("Size of buffer has been increased (%ld, %ld)\n",
926 wh32->dwBufferLength, wh16->dwBufferLength);
927 return MMDRV_MAP_MSGERROR;
928 }
929 wh32->dwBufferLength = wh16->dwBufferLength;
Eric Pouech4853b6d1999-09-22 16:52:47 +0000930 ret = MMDRV_MAP_OKMEM;
931 }
932 break;
933 default:
Eric Pouech31a19331999-11-21 00:51:05 +0000934 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
935 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +0000936 break;
937 }
938 return ret;
939}
940
941/**************************************************************************
942 * MMDRV_WaveIn_UnMap16To32A [internal]
943 */
944static MMDRV_MapType MMDRV_WaveIn_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
945{
946 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
947
948 switch (wMsg) {
949 case WIDM_GETNUMDEVS:
950 case WIDM_RESET:
951 case WIDM_START:
952 case WIDM_STOP:
953 ret = MMDRV_MAP_OK;
954 break;
955 case WIDM_OPEN:
956 case WIDM_CLOSE:
957 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
958 break;
959 case WIDM_GETDEVCAPS:
960 {
961 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)(*lpParam1);
962 LPWAVEINCAPS16 wic16 = *(LPWAVEINCAPS16*)((LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
963
964 wic16->wMid = wic32->wMid;
965 wic16->wPid = wic32->wPid;
966 wic16->vDriverVersion = wic32->vDriverVersion;
967 strcpy(wic16->szPname, wic32->szPname);
968 wic16->dwFormats = wic32->dwFormats;
969 wic16->wChannels = wic32->wChannels;
970 HeapFree(GetProcessHeap(), 0, (LPSTR)wic32 - sizeof(LPWAVEINCAPS16));
971 ret = MMDRV_MAP_OK;
972 }
973 break;
974 case WIDM_GETPOS:
975 {
976 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
977 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
978
979 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
980 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
981 ret = MMDRV_MAP_OK;
982 }
983 break;
984 case WIDM_ADDBUFFER:
985 case WIDM_PREPARE:
986 case WIDM_UNPREPARE:
987 {
988 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
989 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
990
991 assert(wh16->lpNext == wh32);
992 wh16->dwBufferLength = wh32->dwBufferLength;
993 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
994 wh16->dwUser = wh32->dwUser;
995 wh16->dwFlags = wh32->dwFlags;
996 wh16->dwLoops = wh32->dwLoops;
997
998 if (wMsg == WIDM_UNPREPARE) {
999 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1000 wh16->lpNext = 0;
1001 }
1002 ret = MMDRV_MAP_OK;
1003 }
1004 break;
1005 default:
Eric Pouech31a19331999-11-21 00:51:05 +00001006 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +00001007 break;
1008 }
1009 return ret;
1010}
1011
1012/**************************************************************************
1013 * MMDRV_WaveIn_Map32ATo16 [internal]
1014 */
1015static MMDRV_MapType MMDRV_WaveIn_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1016{
1017 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1018
1019 switch (wMsg) {
1020 case WIDM_CLOSE:
1021 case WIDM_GETNUMDEVS:
1022 case WIDM_RESET:
1023 case WIDM_START:
1024 case WIDM_STOP:
1025 ret = MMDRV_MAP_OK;
1026 break;
1027
1028 case WIDM_OPEN:
1029 {
1030 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1031 int sz = sizeof(WAVEFORMATEX);
1032 LPVOID ptr;
1033 LPWAVEOPENDESC16 wod16;
1034
1035 /* allocated data are mapped as follows:
1036 LPWAVEOPENDESC ptr to orig lParam1
Eric Pouech28237782000-01-04 01:04:48 +00001037 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
Eric Pouech4853b6d1999-09-22 16:52:47 +00001038 DWORD dwUser passed to driver
1039 WAVEOPENDESC16 wod16: openDesc passed to driver
1040 WAVEFORMATEX openDesc->lpFormat passed to driver
1041 xxx extra bytes to WAVEFORMATEX
1042 */
1043 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1044 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1045 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1046 }
1047
1048 ptr = SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1049
1050 if (ptr) {
1051 *(LPWAVEOPENDESC*)ptr = wod32;
1052 *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1053 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1054
1055 wod16->hWave = wod32->hWave;
1056 wod16->lpFormat = (LPWAVEFORMATEX)((DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1057 memcpy(wod16 + 1, wod32->lpFormat, sz);
1058
1059 wod16->dwCallback = wod32->dwCallback;
1060 wod16->dwInstance = wod32->dwInstance;
1061 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1062 wod16->dnDevNode = wod32->dnDevNode;
1063
1064 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1065 *lpdwUser = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1066
1067 ret = MMDRV_MAP_OKMEM;
1068 } else {
1069 ret = MMDRV_MAP_NOMEM;
1070 }
1071 }
1072 break;
1073 case WIDM_PREPARE:
1074 {
1075 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1076 LPWAVEHDR wh16;
1077 LPVOID ptr = SEGPTR_ALLOC(sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1078
1079 if (ptr) {
1080 *(LPWAVEHDR*)ptr = wh32;
1081 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1082 wh16->lpData = (LPSTR)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1083 /* data will be copied on WODM_WRITE */
1084 wh16->dwBufferLength = wh32->dwBufferLength;
1085 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1086 wh16->dwUser = wh32->dwUser;
1087 wh16->dwFlags = wh32->dwFlags;
1088 wh16->dwLoops = wh32->dwLoops;
1089 /* FIXME: nothing on wh32->lpNext */
1090 /* could link the wh32->lpNext at this level for memory house keeping */
1091 wh32->lpNext = wh16; /* for reuse in unprepare and write */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001092 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1093 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1094 wh32->dwBufferLength, (DWORD)wh32->lpData);
1095 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
1096 *lpParam2 = sizeof(WAVEHDR);
1097
1098 ret = MMDRV_MAP_OKMEM;
1099 } else {
1100 ret = MMDRV_MAP_NOMEM;
1101 }
1102 }
1103 break;
1104 case WIDM_ADDBUFFER:
1105 case WIDM_UNPREPARE:
1106 {
1107 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1108 LPWAVEHDR wh16 = wh32->lpNext;
1109 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1110
1111 assert(*(LPWAVEHDR*)ptr == wh32);
1112
1113 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1114 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1115 wh32->dwBufferLength, (DWORD)wh32->lpData);
1116
Eric Pouech28237782000-01-04 01:04:48 +00001117 if (wMsg == WIDM_ADDBUFFER)
Eric Pouech4853b6d1999-09-22 16:52:47 +00001118 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1119
1120 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
1121 *lpParam2 = sizeof(WAVEHDR);
Eric Pouech28237782000-01-04 01:04:48 +00001122 /* dwBufferLength can be reduced between prepare & write */
1123 if (wh32->dwBufferLength < wh16->dwBufferLength) {
1124 ERR("Size of buffer has been increased (%ld, %ld)\n",
1125 wh32->dwBufferLength, wh16->dwBufferLength);
1126 return MMDRV_MAP_MSGERROR;
1127 }
1128 wh32->dwBufferLength = wh16->dwBufferLength;
Eric Pouech4853b6d1999-09-22 16:52:47 +00001129 ret = MMDRV_MAP_OKMEM;
1130 }
1131 break;
1132 case WIDM_GETDEVCAPS:
1133 {
1134 LPWAVEINCAPSA wic32 = (LPWAVEINCAPSA)*lpParam1;
1135 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPWAVEINCAPSA) + sizeof(WAVEINCAPS16));
1136
1137 if (ptr) {
1138 *(LPWAVEINCAPSA*)ptr = wic32;
1139 ret = MMDRV_MAP_OKMEM;
1140 } else {
1141 ret = MMDRV_MAP_NOMEM;
1142 }
1143 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEINCAPSA);
1144 *lpParam2 = sizeof(WAVEINCAPS16);
1145 }
1146 break;
1147 case WIDM_GETPOS:
1148 {
1149 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1150 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPMMTIME) + sizeof(MMTIME16));
1151 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1152
1153 if (ptr) {
1154 *(LPMMTIME*)ptr = mmt32;
1155 mmt16->wType = mmt32->wType;
1156 ret = MMDRV_MAP_OKMEM;
1157 } else {
1158 ret = MMDRV_MAP_NOMEM;
1159 }
1160 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMMTIME);
1161 *lpParam2 = sizeof(MMTIME16);
1162 }
1163 break;
1164 default:
Eric Pouech31a19331999-11-21 00:51:05 +00001165 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +00001166 break;
1167 }
1168 return ret;
1169}
1170
1171/**************************************************************************
1172 * MMDRV_WaveIn_UnMap32ATo16 [internal]
1173 */
1174static MMDRV_MapType MMDRV_WaveIn_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1175{
1176 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1177
1178 switch (wMsg) {
1179 case WIDM_CLOSE:
1180 case WIDM_GETNUMDEVS:
1181 case WIDM_RESET:
1182 case WIDM_START:
1183 case WIDM_STOP:
1184 ret = MMDRV_MAP_OK;
1185 break;
1186
1187 case WIDM_OPEN:
1188 {
1189 LPWAVEOPENDESC16 wod16 = (LPWAVEOPENDESC16)PTR_SEG_TO_LIN(*lpParam1);
1190 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1191 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1192
1193 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1194 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1195
1196 if (!SEGPTR_FREE(ptr))
1197 FIXME("bad free line=%d\n", __LINE__);
1198
1199 ret = MMDRV_MAP_OK;
1200 }
1201 break;
1202
1203 case WIDM_ADDBUFFER:
1204 case WIDM_PREPARE:
1205 case WIDM_UNPREPARE:
1206 {
1207 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(*lpParam1);
1208 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1209 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1210
1211 assert(wh32->lpNext == wh16);
1212 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1213 wh32->dwUser = wh16->dwUser;
1214 wh32->dwFlags = wh16->dwFlags;
1215 wh32->dwLoops = wh16->dwLoops;
1216
Eric Pouech28237782000-01-04 01:04:48 +00001217 if (wMsg == WIDM_UNPREPARE) {
Eric Pouech4853b6d1999-09-22 16:52:47 +00001218 if (!SEGPTR_FREE(ptr))
1219 FIXME("bad free line=%d\n", __LINE__);
1220 wh32->lpNext = 0;
1221 }
1222 ret = MMDRV_MAP_OK;
1223 }
1224 break;
1225 case WIDM_GETDEVCAPS:
1226 {
1227 LPWAVEINCAPS16 wic16 = (LPWAVEINCAPS16)PTR_SEG_TO_LIN(*lpParam1);
1228 LPSTR ptr = (LPSTR)wic16 - sizeof(LPWAVEINCAPSA);
1229 LPWAVEINCAPSA wic32 = *(LPWAVEINCAPSA*)ptr;
1230
1231 wic32->wMid = wic16->wMid;
1232 wic32->wPid = wic16->wPid;
1233 wic32->vDriverVersion = wic16->vDriverVersion;
1234 strcpy(wic32->szPname, wic16->szPname);
1235 wic32->dwFormats = wic16->dwFormats;
1236 wic32->wChannels = wic16->wChannels;
1237 if (!SEGPTR_FREE(ptr))
1238 FIXME("bad free line=%d\n", __LINE__);
1239 ret = MMDRV_MAP_OK;
1240 }
1241 break;
1242 case WIDM_GETPOS:
1243 {
1244 LPMMTIME16 mmt16 = (LPMMTIME16)PTR_SEG_TO_LIN(*lpParam1);
1245 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1246 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1247
1248 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1249
1250 if (!SEGPTR_FREE(ptr))
1251 FIXME("bad free line=%d\n", __LINE__);
1252
1253 ret = MMDRV_MAP_OK;
1254 }
1255 break;
1256 default:
Eric Pouech31a19331999-11-21 00:51:05 +00001257 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +00001258 break;
1259 }
1260 return ret;
1261}
1262
1263/**************************************************************************
1264 * MMDRV_WaveIn_Callback [internal]
1265 */
1266static void CALLBACK MMDRV_WaveIn_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1267{
1268 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1269
1270 switch (uMsg) {
1271 case WIM_OPEN:
1272 case WIM_CLOSE:
1273 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1274 break;
1275 case WIM_DATA:
1276 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1277 /* initial map is: 32 => 16 */
1278 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1);
1279 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1280
1281 dwParam1 = (DWORD)wh32;
1282 wh32->dwFlags = wh16->dwFlags;
1283 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1284 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1285 /* initial map is: 16 => 32 */
1286 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1287 LPWAVEHDR segwh16 = *(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1288 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(segwh16);
1289
1290 dwParam1 = (DWORD)segwh16;
1291 wh16->dwFlags = wh32->dwFlags;
1292 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1293 }
1294 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1295 break;
1296 default:
1297 ERR("Unknown msg %u\n", uMsg);
1298 }
1299
1300 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1301}
1302
1303/* =================================
1304 * W A V E O U T M A P P E R S
1305 * ================================= */
1306
1307/**************************************************************************
1308 * MMDRV_WaveOut_Map16To32A [internal]
1309 */
1310static MMDRV_MapType MMDRV_WaveOut_Map16To32A (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1311{
1312 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1313
1314 switch (wMsg) {
1315 /* nothing to do */
1316 case WODM_BREAKLOOP:
1317 case WODM_CLOSE:
1318 case WODM_GETNUMDEVS:
1319 case WODM_PAUSE:
1320 case WODM_RESET:
1321 case WODM_RESTART:
1322 case WODM_SETPITCH:
1323 case WODM_SETPLAYBACKRATE:
1324 case WODM_SETVOLUME:
1325 ret = MMDRV_MAP_OK;
1326 break;
1327
1328 case WODM_GETPITCH:
1329 case WODM_GETPLAYBACKRATE:
1330 case WODM_GETVOLUME:
1331 case WODM_OPEN:
1332 FIXME("Shouldn't be used: the corresponding 16 bit functions use the 32 bit interface\n");
1333 break;
1334
1335 case WODM_GETDEVCAPS:
1336 {
1337 LPWAVEOUTCAPSA woc32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEOUTCAPS16) + sizeof(WAVEOUTCAPSA));
1338 LPWAVEOUTCAPS16 woc16 = PTR_SEG_TO_LIN(*lpParam1);
1339
1340 if (woc32) {
1341 *(LPWAVEOUTCAPS16*)woc32 = woc16;
1342 woc32 = (LPWAVEOUTCAPSA)((LPSTR)woc32 + sizeof(LPWAVEOUTCAPS16));
1343 *lpParam1 = (DWORD)woc32;
1344 *lpParam2 = sizeof(WAVEOUTCAPSA);
1345
1346 ret = MMDRV_MAP_OKMEM;
1347 } else {
1348 ret = MMDRV_MAP_NOMEM;
1349 }
1350 }
1351 break;
1352 case WODM_GETPOS:
1353 {
1354 LPMMTIME mmt32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMMTIME16) + sizeof(MMTIME));
1355 LPMMTIME16 mmt16 = PTR_SEG_TO_LIN(*lpParam1);
1356
1357 if (mmt32) {
1358 *(LPMMTIME16*)mmt32 = mmt16;
1359 mmt32 = (LPMMTIME)((LPSTR)mmt32 + sizeof(LPMMTIME16));
1360
1361 mmt32->wType = mmt16->wType;
1362 *lpParam1 = (DWORD)mmt32;
1363 *lpParam2 = sizeof(MMTIME);
1364
1365 ret = MMDRV_MAP_OKMEM;
1366 } else {
1367 ret = MMDRV_MAP_NOMEM;
1368 }
1369 }
1370 break;
1371 case WODM_PREPARE:
1372 {
1373 LPWAVEHDR wh32 = HeapAlloc(GetProcessHeap(), 0, sizeof(LPWAVEHDR) + sizeof(WAVEHDR));
1374 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
1375
1376 if (wh32) {
1377 *(LPWAVEHDR*)wh32 = (LPWAVEHDR)*lpParam1;
1378 wh32 = (LPWAVEHDR)((LPSTR)wh32 + sizeof(LPWAVEHDR));
1379 wh32->lpData = PTR_SEG_TO_LIN(wh16->lpData);
1380 wh32->dwBufferLength = wh16->dwBufferLength;
1381 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1382 wh32->dwUser = wh16->dwUser;
1383 wh32->dwFlags = wh16->dwFlags;
1384 wh32->dwLoops = wh16->dwLoops;
1385 /* FIXME: nothing on wh32->lpNext */
1386 /* could link the wh32->lpNext at this level for memory house keeping */
1387 wh16->lpNext = wh32; /* for reuse in unprepare and write */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001388 *lpParam1 = (DWORD)wh32;
1389 *lpParam2 = sizeof(WAVEHDR);
1390
1391 ret = MMDRV_MAP_OKMEM;
1392 } else {
1393 ret = MMDRV_MAP_NOMEM;
1394 }
1395 }
1396 break;
1397 case WODM_UNPREPARE:
1398 case WODM_WRITE:
1399 {
1400 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*lpParam1);
1401 LPWAVEHDR wh32 = (LPWAVEHDR)wh16->lpNext;
1402
1403 *lpParam1 = (DWORD)wh32;
1404 *lpParam2 = sizeof(WAVEHDR);
Eric Pouech28237782000-01-04 01:04:48 +00001405 /* dwBufferLength can be reduced between prepare & write */
1406 if (wh32->dwBufferLength < wh16->dwBufferLength) {
1407 ERR("Size of buffer has been increased (%ld, %ld)\n",
1408 wh32->dwBufferLength, wh16->dwBufferLength);
1409 return MMDRV_MAP_MSGERROR;
1410 }
1411 wh32->dwBufferLength = wh16->dwBufferLength;
Eric Pouech4853b6d1999-09-22 16:52:47 +00001412 ret = MMDRV_MAP_OKMEM;
1413 }
1414 break;
1415 default:
Eric Pouech31a19331999-11-21 00:51:05 +00001416 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +00001417 break;
1418 }
1419 return ret;
1420}
1421
1422/**************************************************************************
1423 * MMDRV_WaveOut_UnMap16To32A [internal]
1424 */
1425static MMDRV_MapType MMDRV_WaveOut_UnMap16To32A(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1426{
1427 MMDRV_MapType ret = MMDRV_MAP_MSGERROR;
1428
1429 switch (wMsg) {
1430 /* nothing to do */
1431 case WODM_BREAKLOOP:
1432 case WODM_CLOSE:
1433 case WODM_GETNUMDEVS:
1434 case WODM_PAUSE:
1435 case WODM_RESET:
1436 case WODM_RESTART:
1437 case WODM_SETPITCH:
1438 case WODM_SETPLAYBACKRATE:
1439 case WODM_SETVOLUME:
1440 ret = MMDRV_MAP_OK;
1441 break;
1442
1443 case WODM_GETPITCH:
1444 case WODM_GETPLAYBACKRATE:
1445 case WODM_GETVOLUME:
1446 case WODM_OPEN:
1447 FIXME("Shouldn't be used: those 16 bit functions use the 32 bit interface\n");
1448 break;
1449
1450 case WODM_GETDEVCAPS:
1451 {
1452 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)(*lpParam1);
1453 LPWAVEOUTCAPS16 woc16 = *(LPWAVEOUTCAPS16*)((LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1454
1455 woc16->wMid = woc32->wMid;
1456 woc16->wPid = woc32->wPid;
1457 woc16->vDriverVersion = woc32->vDriverVersion;
1458 strcpy(woc16->szPname, woc32->szPname);
1459 woc16->dwFormats = woc32->dwFormats;
1460 woc16->wChannels = woc32->wChannels;
1461 woc16->dwSupport = woc32->dwSupport;
1462 HeapFree(GetProcessHeap(), 0, (LPSTR)woc32 - sizeof(LPWAVEOUTCAPS16));
1463 ret = MMDRV_MAP_OK;
1464 }
1465 break;
1466 case WODM_GETPOS:
1467 {
1468 LPMMTIME mmt32 = (LPMMTIME)(*lpParam1);
1469 LPMMTIME16 mmt16 = *(LPMMTIME16*)((LPSTR)mmt32 - sizeof(LPMMTIME16));
1470
1471 MMSYSTEM_MMTIME32to16(mmt16, mmt32);
1472 HeapFree(GetProcessHeap(), 0, (LPSTR)mmt32 - sizeof(LPMMTIME16));
1473 ret = MMDRV_MAP_OK;
1474 }
1475 break;
1476 case WODM_PREPARE:
1477 case WODM_UNPREPARE:
1478 case WODM_WRITE:
1479 {
1480 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1481 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(*(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR)));
1482
1483 assert(wh16->lpNext == wh32);
1484 wh16->dwBufferLength = wh32->dwBufferLength;
1485 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1486 wh16->dwUser = wh32->dwUser;
1487 wh16->dwFlags = wh32->dwFlags;
1488 wh16->dwLoops = wh32->dwLoops;
1489
1490 if (wMsg == WODM_UNPREPARE) {
1491 HeapFree(GetProcessHeap(), 0, (LPSTR)wh32 - sizeof(LPWAVEHDR));
1492 wh16->lpNext = 0;
1493 }
1494 ret = MMDRV_MAP_OK;
1495 }
1496 break;
1497 default:
Eric Pouech31a19331999-11-21 00:51:05 +00001498 FIXME("NIY: no conversion yet for %u [%lx,%lx]\n", wMsg, *lpParam1, *lpParam2);
Eric Pouech4853b6d1999-09-22 16:52:47 +00001499 break;
1500 }
1501 return ret;
1502}
1503
1504/**************************************************************************
1505 * MMDRV_WaveOut_Map32ATo16 [internal]
1506 */
1507static MMDRV_MapType MMDRV_WaveOut_Map32ATo16 (UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1508{
1509 MMDRV_MapType ret;
1510
1511 switch (wMsg) {
1512 /* nothing to do */
1513 case WODM_BREAKLOOP:
1514 case WODM_CLOSE:
1515 case WODM_GETNUMDEVS:
1516 case WODM_PAUSE:
1517 case WODM_RESET:
1518 case WODM_RESTART:
1519 case WODM_SETPITCH:
1520 case WODM_SETPLAYBACKRATE:
1521 case WODM_SETVOLUME:
1522 ret = MMDRV_MAP_OK;
1523 break;
1524
1525 case WODM_GETDEVCAPS:
1526 {
1527 LPWAVEOUTCAPSA woc32 = (LPWAVEOUTCAPSA)*lpParam1;
1528 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPWAVEOUTCAPSA) + sizeof(WAVEOUTCAPS16));
1529
1530 if (ptr) {
1531 *(LPWAVEOUTCAPSA*)ptr = woc32;
1532 ret = MMDRV_MAP_OKMEM;
1533 } else {
1534 ret = MMDRV_MAP_NOMEM;
1535 }
1536 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOUTCAPSA);
1537 *lpParam2 = sizeof(WAVEOUTCAPS16);
1538 }
1539 break;
1540 case WODM_GETPITCH:
1541 FIXME("NIY: no conversion yet\n");
1542 ret = MMDRV_MAP_MSGERROR;
1543 break;
1544 case WODM_GETPLAYBACKRATE:
1545 FIXME("NIY: no conversion yet\n");
1546 ret = MMDRV_MAP_MSGERROR;
1547 break;
1548 case WODM_GETPOS:
1549 {
1550 LPMMTIME mmt32 = (LPMMTIME)*lpParam1;
1551 LPSTR ptr = SEGPTR_ALLOC(sizeof(LPMMTIME) + sizeof(MMTIME16));
1552 LPMMTIME16 mmt16 = (LPMMTIME16)(ptr + sizeof(LPMMTIME));
1553
1554 if (ptr) {
1555 *(LPMMTIME*)ptr = mmt32;
1556 mmt16->wType = mmt32->wType;
1557 ret = MMDRV_MAP_OKMEM;
1558 } else {
1559 ret = MMDRV_MAP_NOMEM;
1560 }
1561 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPMMTIME);
1562 *lpParam2 = sizeof(MMTIME16);
1563 }
1564 break;
1565 case WODM_GETVOLUME:
1566 FIXME("NIY: no conversion yet\n");
1567 ret = MMDRV_MAP_MSGERROR;
1568 break;
1569 case WODM_OPEN:
1570 {
1571 LPWAVEOPENDESC wod32 = (LPWAVEOPENDESC)*lpParam1;
1572 int sz = sizeof(WAVEFORMATEX);
1573 LPVOID ptr;
1574 LPWAVEOPENDESC16 wod16;
1575
1576 /* allocated data are mapped as follows:
1577 LPWAVEOPENDESC ptr to orig lParam1
Eric Pouech28237782000-01-04 01:04:48 +00001578 DWORD orig dwUser, which is a pointer to DWORD:driver dwInstance
Eric Pouech4853b6d1999-09-22 16:52:47 +00001579 DWORD dwUser passed to driver
1580 WAVEOPENDESC16 wod16: openDesc passed to driver
1581 WAVEFORMATEX openDesc->lpFormat passed to driver
1582 xxx extra bytes to WAVEFORMATEX
1583 */
1584 if (wod32->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
1585 TRACE("Allocating %u extra bytes (%d)\n", ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize, wod32->lpFormat->wFormatTag);
1586 sz += ((LPWAVEFORMATEX)wod32->lpFormat)->cbSize;
1587 }
1588
1589 ptr = SEGPTR_ALLOC(sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16) + sz);
1590
1591 if (ptr) {
1592 *(LPWAVEOPENDESC*)ptr = wod32;
1593 *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC)) = *lpdwUser;
1594 wod16 = (LPWAVEOPENDESC16)((LPSTR)ptr + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD));
1595
1596 wod16->hWave = wod32->hWave;
1597 wod16->lpFormat = (LPWAVEFORMATEX)((DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD) + sizeof(WAVEOPENDESC16));
1598 memcpy(wod16 + 1, wod32->lpFormat, sz);
1599
1600 wod16->dwCallback = wod32->dwCallback;
1601 wod16->dwInstance = wod32->dwInstance;
1602 wod16->uMappedDeviceID = wod32->uMappedDeviceID;
1603 wod16->dnDevNode = wod32->dnDevNode;
1604
1605 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + 2*sizeof(DWORD);
1606 *lpdwUser = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEOPENDESC) + sizeof(DWORD);
1607
1608 ret = MMDRV_MAP_OKMEM;
1609 } else {
1610 ret = MMDRV_MAP_NOMEM;
1611 }
1612 }
1613 break;
1614 case WODM_PREPARE:
1615 {
1616 LPWAVEHDR wh32 = (LPWAVEHDR)*lpParam1;
1617 LPWAVEHDR wh16;
1618 LPVOID ptr = SEGPTR_ALLOC(sizeof(LPWAVEHDR) + sizeof(WAVEHDR) + wh32->dwBufferLength);
1619
1620 if (ptr) {
1621 *(LPWAVEHDR*)ptr = wh32;
1622 wh16 = (LPWAVEHDR)((LPSTR)ptr + sizeof(LPWAVEHDR));
1623 wh16->lpData = (LPSTR)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR) + sizeof(WAVEHDR);
1624 /* data will be copied on WODM_WRITE */
1625 wh16->dwBufferLength = wh32->dwBufferLength;
1626 wh16->dwBytesRecorded = wh32->dwBytesRecorded;
1627 wh16->dwUser = wh32->dwUser;
1628 wh16->dwFlags = wh32->dwFlags;
1629 wh16->dwLoops = wh32->dwLoops;
1630 /* FIXME: nothing on wh32->lpNext */
1631 /* could link the wh32->lpNext at this level for memory house keeping */
1632 wh32->lpNext = wh16; /* for reuse in unprepare and write */
Eric Pouech4853b6d1999-09-22 16:52:47 +00001633 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1634 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1635 wh32->dwBufferLength, (DWORD)wh32->lpData);
1636 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
1637 *lpParam2 = sizeof(WAVEHDR);
1638
1639 ret = MMDRV_MAP_OKMEM;
1640 } else {
1641 ret = MMDRV_MAP_NOMEM;
1642 }
1643 }
1644 break;
1645 case WODM_UNPREPARE:
1646 case WODM_WRITE:
1647 {
1648 LPWAVEHDR wh32 = (LPWAVEHDR)(*lpParam1);
1649 LPWAVEHDR wh16 = wh32->lpNext;
1650 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1651
1652 assert(*(LPWAVEHDR*)ptr == wh32);
1653
1654 TRACE("wh16=%08lx wh16->lpData=%08lx wh32->buflen=%lu wh32->lpData=%08lx\n",
1655 (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR), (DWORD)wh16->lpData,
1656 wh32->dwBufferLength, (DWORD)wh32->lpData);
1657
1658 if (wMsg == WODM_WRITE)
1659 memcpy((LPSTR)wh16 + sizeof(WAVEHDR), wh32->lpData, wh32->dwBufferLength);
1660
1661 *lpParam1 = (DWORD)SEGPTR_GET(ptr) + sizeof(LPWAVEHDR);
1662 *lpParam2 = sizeof(WAVEHDR);
Eric Pouech28237782000-01-04 01:04:48 +00001663 /* dwBufferLength can be reduced between prepare & write */
1664 if (wh16->dwBufferLength < wh32->dwBufferLength) {
1665 ERR("Size of buffer has been increased (%ld, %ld)\n",
1666 wh16->dwBufferLength, wh32->dwBufferLength);
1667 return MMDRV_MAP_MSGERROR;
1668 }
1669 wh16->dwBufferLength = wh32->dwBufferLength;
Eric Pouech4853b6d1999-09-22 16:52:47 +00001670 ret = MMDRV_MAP_OKMEM;
1671 }
1672 break;
1673 default:
1674 FIXME("NIY: no conversion yet\n");
1675 ret = MMDRV_MAP_MSGERROR;
1676 break;
1677 }
1678 return ret;
1679}
1680
1681/**************************************************************************
1682 * MMDRV_WaveOut_UnMap32ATo16 [internal]
1683 */
1684static MMDRV_MapType MMDRV_WaveOut_UnMap32ATo16(UINT wMsg, LPDWORD lpdwUser, LPDWORD lpParam1, LPDWORD lpParam2)
1685{
1686 MMDRV_MapType ret;
1687
1688 switch (wMsg) {
1689 /* nothing to do */
1690 case WODM_BREAKLOOP:
1691 case WODM_CLOSE:
1692 case WODM_GETNUMDEVS:
1693 case WODM_PAUSE:
1694 case WODM_RESET:
1695 case WODM_RESTART:
1696 case WODM_SETPITCH:
1697 case WODM_SETPLAYBACKRATE:
1698 case WODM_SETVOLUME:
1699 ret = MMDRV_MAP_OK;
1700 break;
1701
1702 case WODM_GETDEVCAPS:
1703 {
1704 LPWAVEOUTCAPS16 woc16 = (LPWAVEOUTCAPS16)PTR_SEG_TO_LIN(*lpParam1);
1705 LPSTR ptr = (LPSTR)woc16 - sizeof(LPWAVEOUTCAPSA);
1706 LPWAVEOUTCAPSA woc32 = *(LPWAVEOUTCAPSA*)ptr;
1707
1708 woc32->wMid = woc16->wMid;
1709 woc32->wPid = woc16->wPid;
1710 woc32->vDriverVersion = woc16->vDriverVersion;
1711 strcpy(woc32->szPname, woc16->szPname);
1712 woc32->dwFormats = woc16->dwFormats;
1713 woc32->wChannels = woc16->wChannels;
1714 woc32->dwSupport = woc16->dwSupport;
1715 if (!SEGPTR_FREE(ptr))
1716 FIXME("bad free line=%d\n", __LINE__);
1717 ret = MMDRV_MAP_OK;
1718 }
1719 break;
1720 case WODM_GETPITCH:
1721 FIXME("NIY: no conversion yet\n");
1722 ret = MMDRV_MAP_MSGERROR;
1723 break;
1724 case WODM_GETPLAYBACKRATE:
1725 FIXME("NIY: no conversion yet\n");
1726 ret = MMDRV_MAP_MSGERROR;
1727 break;
1728 case WODM_GETPOS:
1729 {
1730 LPMMTIME16 mmt16 = (LPMMTIME16)PTR_SEG_TO_LIN(*lpParam1);
1731 LPSTR ptr = (LPSTR)mmt16 - sizeof(LPMMTIME);
1732 LPMMTIME mmt32 = *(LPMMTIME*)ptr;
1733
1734 MMSYSTEM_MMTIME16to32(mmt32, mmt16);
1735
1736 if (!SEGPTR_FREE(ptr))
1737 FIXME("bad free line=%d\n", __LINE__);
1738
1739 ret = MMDRV_MAP_OK;
1740 }
1741 break;
1742 case WODM_OPEN:
1743 {
1744 LPWAVEOPENDESC16 wod16 = (LPWAVEOPENDESC16)PTR_SEG_TO_LIN(*lpParam1);
1745 LPSTR ptr = (LPSTR)wod16 - sizeof(LPWAVEOPENDESC) - 2*sizeof(DWORD);
1746 LPWAVEOPENDESC wod32 = *(LPWAVEOPENDESC*)ptr;
1747
1748 wod32->uMappedDeviceID = wod16->uMappedDeviceID;
1749 **(DWORD**)(ptr + sizeof(LPWAVEOPENDESC)) = *(LPDWORD)(ptr + sizeof(LPWAVEOPENDESC) + sizeof(DWORD));
1750
1751 if (!SEGPTR_FREE(ptr))
1752 FIXME("bad free line=%d\n", __LINE__);
1753
1754 ret = MMDRV_MAP_OK;
1755 }
1756 break;
1757 case WODM_PREPARE:
1758 case WODM_UNPREPARE:
1759 case WODM_WRITE:
1760 {
1761 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(*lpParam1);
1762 LPSTR ptr = (LPSTR)wh16 - sizeof(LPWAVEHDR);
1763 LPWAVEHDR wh32 = *(LPWAVEHDR*)ptr;
1764
1765 assert(wh32->lpNext == wh16);
1766 wh32->dwBytesRecorded = wh16->dwBytesRecorded;
1767 wh32->dwUser = wh16->dwUser;
1768 wh32->dwFlags = wh16->dwFlags;
1769 wh32->dwLoops = wh16->dwLoops;
1770
1771 if (wMsg == WODM_UNPREPARE) {
1772 if (!SEGPTR_FREE(ptr))
1773 FIXME("bad free line=%d\n", __LINE__);
1774 wh32->lpNext = 0;
1775 }
1776 ret = MMDRV_MAP_OK;
1777 }
1778 break;
1779 case WODM_GETVOLUME:
1780 FIXME("NIY: no conversion yet\n");
1781 ret = MMDRV_MAP_MSGERROR;
1782 break;
1783 default:
1784 FIXME("NIY: no conversion yet\n");
1785 ret = MMDRV_MAP_MSGERROR;
1786 break;
1787 }
1788 return ret;
1789}
1790
1791/**************************************************************************
1792 * MMDRV_WaveOut_Callback [internal]
1793 */
1794static void CALLBACK MMDRV_WaveOut_Callback(HDRVR hDev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
1795{
1796 LPWINE_MLD mld = (LPWINE_MLD)dwInstance;
1797
1798 switch (uMsg) {
1799 case WOM_OPEN:
1800 case WOM_CLOSE:
1801 /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
1802 break;
1803 case WOM_DONE:
1804 if (mld->bFrom32 && !MMDrvs[mld->mmdIndex].bIs32) {
1805 /* initial map is: 32 => 16 */
1806 LPWAVEHDR wh16 = (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1);
1807 LPWAVEHDR wh32 = *(LPWAVEHDR*)((LPSTR)wh16 - sizeof(LPWAVEHDR));
1808
1809 dwParam1 = (DWORD)wh32;
1810 wh32->dwFlags = wh16->dwFlags;
1811 } else if (!mld->bFrom32 && MMDrvs[mld->mmdIndex].bIs32) {
1812 /* initial map is: 16 => 32 */
1813 LPWAVEHDR wh32 = (LPWAVEHDR)(dwParam1);
1814 LPWAVEHDR segwh16 = *(LPWAVEHDR*)((LPSTR)wh32 - sizeof(LPWAVEHDR));
1815 LPWAVEHDR wh16 = PTR_SEG_TO_LIN(segwh16);
1816
1817 dwParam1 = (DWORD)segwh16;
1818 wh16->dwFlags = wh32->dwFlags;
1819 }
1820 /* else { 16 => 16 or 32 => 32, nothing to do, same struct is kept }*/
1821 break;
1822 default:
1823 ERR("Unknown msg %u\n", uMsg);
1824 }
1825
1826 MMDRV_Callback(mld, hDev, uMsg, dwParam1, dwParam2);
1827}
1828
1829#define A(_x,_y) {#_y, _x, \
1830MMDRV_##_y##_Map16To32A, MMDRV_##_y##_UnMap16To32A, \
1831MMDRV_##_y##_Map32ATo16, MMDRV_##_y##_UnMap32ATo16, \
1832MMDRV_##_y##_Callback, 0, NULL, -1}
1833
1834/* Note: the indices of this array must match the definitions
1835 * of the MMDRV_???? manifest constants
1836 */
1837static WINE_LLTYPE llTypes[MMDRV_MAX] = {
1838 A(TRUE, Aux),
1839 A(FALSE, Mixer),
1840 A(TRUE, MidiIn),
1841 A(TRUE, MidiOut),
1842 A(TRUE, WaveIn),
1843 A(TRUE, WaveOut),
1844};
1845#undef A
1846
1847/**************************************************************************
1848 * MMDRV_GetNum [internal]
1849 */
1850UINT MMDRV_GetNum(UINT type)
1851{
1852 assert(type < MMDRV_MAX);
1853 return llTypes[type].wMaxId;
1854}
1855
1856/**************************************************************************
1857 * WINE_Message [internal]
1858 */
1859DWORD MMDRV_Message(LPWINE_MLD mld, WORD wMsg, DWORD dwParam1,
1860 DWORD dwParam2, BOOL bFrom32)
1861{
1862 LPWINE_MM_DRIVER lpDrv;
1863 DWORD ret;
1864 WINE_MM_DRIVER_PART* part;
1865 WINE_LLTYPE* llType = &llTypes[mld->type];
1866 MMDRV_MapType map;
1867 int devID;
1868
1869 TRACE("(%s %u %u 0x%08lx 0x%08lx 0x%08lx %c)!\n",
1870 llTypes[mld->type].name, mld->uDeviceID, wMsg,
1871 mld->dwDriverInstance, dwParam1, dwParam2, bFrom32?'Y':'N');
1872
1873 if (mld->uDeviceID == (UINT16)-1) {
1874 if (!llType->bSupportMapper) {
1875 WARN("uDev=-1 requested on non-mappable ll type %s\n",
1876 llTypes[mld->type].name);
1877 return MMSYSERR_BADDEVICEID;
1878 }
1879 devID = -1;
1880 } else {
1881 if (mld->uDeviceID >= llType->wMaxId) {
1882 WARN("uDev(%u) requested >= max (%d)\n", mld->uDeviceID, llType->wMaxId);
1883 return MMSYSERR_BADDEVICEID;
1884 }
1885 devID = mld->uDeviceID;
1886 }
1887
1888 lpDrv = &MMDrvs[mld->mmdIndex];
1889 part = &lpDrv->parts[mld->type];
1890
1891#if 0
1892 /* some sanity checks */
1893 if (!(part->nIDMin <= devID))
1894 ERR("!(part->nIDMin(%d) <= devID(%d))\n", part->nIDMin, devID);
1895 if (!(devID < part->nIDMax))
1896 ERR("!(devID(%d) < part->nIDMax(%d))\n", devID, part->nIDMax);
1897#endif
1898
1899 if (lpDrv->bIs32) {
1900 assert(part->u.fnMessage32);
1901
1902 if (bFrom32) {
1903 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1904 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1905 ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1906 TRACE("=> %lu\n", ret);
1907 } else {
1908 map = llType->Map16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1909 switch (map) {
1910 case MMDRV_MAP_NOMEM:
1911 ret = MMSYSERR_NOMEM;
1912 break;
1913 case MMDRV_MAP_MSGERROR:
1914 FIXME("NIY: no conversion yet 16->32 (%u)\n", wMsg);
1915 ret = MMSYSERR_ERROR;
1916 break;
1917 case MMDRV_MAP_OK:
1918 case MMDRV_MAP_OKMEM:
1919 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1920 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1921 ret = part->u.fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance,
1922 dwParam1, dwParam2);
1923 TRACE("=> %lu\n", ret);
1924 if (map == MMDRV_MAP_OKMEM)
1925 llType->UnMap16To32A(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1926 break;
1927 default:
1928 case MMDRV_MAP_PASS:
1929 FIXME("NIY: pass used ?\n");
1930 ret = MMSYSERR_NOTSUPPORTED;
1931 break;
1932 }
1933 }
1934 } else {
1935 assert(part->u.fnMessage16);
1936
1937 if (bFrom32) {
1938 map = llType->Map32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1939 switch (map) {
1940 case MMDRV_MAP_NOMEM:
1941 ret = MMSYSERR_NOMEM;
1942 break;
1943 case MMDRV_MAP_MSGERROR:
1944 FIXME("NIY: no conversion yet 32->16 (%u)\n", wMsg);
1945 ret = MMSYSERR_ERROR;
1946 break;
1947 case MMDRV_MAP_OK:
1948 case MMDRV_MAP_OKMEM:
1949 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1950 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1951 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
1952 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1953 TRACE("=> %lu\n", ret);
1954 if (map == MMDRV_MAP_OKMEM)
1955 llType->UnMap32ATo16(wMsg, &mld->dwDriverInstance, &dwParam1, &dwParam2);
1956 break;
1957 default:
1958 case MMDRV_MAP_PASS:
1959 FIXME("NIY: pass used ?\n");
1960 ret = MMSYSERR_NOTSUPPORTED;
1961 break;
1962 }
1963 } else {
1964 TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx\n",
1965 mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1966 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16, mld->uDeviceID,
1967 wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
1968 TRACE("=> %lu\n", ret);
1969 }
1970 }
1971 return ret;
1972}
1973
1974/**************************************************************************
1975 * MMDRV_Alloc [internal]
1976 */
1977LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
1978 DWORD* dwCallback, DWORD* dwInstance, BOOL bFrom32)
1979{
1980 LPWINE_MLD mld;
1981
1982 if ((*hndl = USER_HEAP_ALLOC(size)) == 0)
1983 return NULL;
1984
1985 mld = (LPWINE_MLD) USER_HEAP_LIN_ADDR(*hndl);
1986 if (!mld) return NULL;
1987 mld->type = type;
1988 if ((UINT)*hndl < MMDRV_GetNum(type) || HIWORD(*hndl) != 0) {
1989 /* FIXME: those conditions must be fulfilled so that:
1990 * - we can distinguish between device IDs and handles
1991 * - we can use handles as 16 or 32 bit entities
1992 */
1993 ERR("Shouldn't happen. Bad allocation scheme\n");
1994 }
1995
1996 mld->bFrom32 = bFrom32;
1997 mld->dwFlags = HIWORD(*dwFlags);
1998 mld->dwCallback = *dwCallback;
1999 mld->dwClientInstance = *dwInstance;
2000
2001 *dwFlags = LOWORD(*dwFlags) | CALLBACK_FUNCTION;
2002 *dwCallback = (DWORD)llTypes[type].Callback;
2003 *dwInstance = (DWORD)mld; /* FIXME: wouldn't some 16 bit drivers only use the loword ? */
2004
2005 return mld;
2006}
2007
2008/**************************************************************************
2009 * MMDRV_Free [internal]
2010 */
2011void MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
2012{
2013 USER_HEAP_FREE(hndl);
2014}
2015
2016/**************************************************************************
2017 * MMDRV_Open [internal]
2018 */
2019DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD dwParam1, DWORD dwFlags)
2020{
2021 DWORD dwRet = MMSYSERR_BADDEVICEID;
2022 DWORD dwInstance;
2023 WINE_LLTYPE* llType = &llTypes[mld->type];
2024
2025 mld->dwDriverInstance = (DWORD)&dwInstance;
2026
Eric Pouech28237782000-01-04 01:04:48 +00002027 if (mld->uDeviceID == (UINT)-1 || mld->uDeviceID == (UINT16)-1) {
Eric Pouech4853b6d1999-09-22 16:52:47 +00002028 TRACE("MAPPER mode requested !\n");
2029 /* check if mapper is supported by type */
2030 if (llType->bSupportMapper) {
2031 if (llType->nMapper == -1) {
2032 /* no driver for mapper has been loaded, try a dumb implementation */
2033 TRACE("No mapper loaded, doing it by hand\n");
2034 for (mld->uDeviceID = 0; mld->uDeviceID < llType->wMaxId; mld->uDeviceID++) {
2035 if ((dwRet = MMDRV_Open(mld, wMsg, dwParam1, dwFlags)) == MMSYSERR_NOERROR) {
2036 /* to share this function epilog */
2037 dwInstance = mld->dwDriverInstance;
2038 break;
2039 }
2040 }
2041 } else {
Eric Pouech31a19331999-11-21 00:51:05 +00002042 mld->uDeviceID = (UINT16)-1;
Eric Pouech4853b6d1999-09-22 16:52:47 +00002043 mld->mmdIndex = llType->lpMlds[-1].mmdIndex;
2044 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
2045 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
2046 }
2047 }
2048 } else {
2049 if (mld->uDeviceID < llType->wMaxId) {
2050 mld->mmdIndex = llType->lpMlds[mld->uDeviceID].mmdIndex;
2051 TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
2052 dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags, TRUE);
2053 }
2054 }
2055 if (dwRet == MMSYSERR_NOERROR)
2056 mld->dwDriverInstance = dwInstance;
2057 return dwRet;
2058}
2059
2060/**************************************************************************
2061 * MMDRV_Close [internal]
2062 */
2063DWORD MMDRV_Close(LPWINE_MLD mld, UINT wMsg)
2064{
2065 return MMDRV_Message(mld, wMsg, 0L, 0L, TRUE);
2066}
2067
2068/**************************************************************************
Eric Pouech31a19331999-11-21 00:51:05 +00002069 * MMDRV_GetByID [internal]
Eric Pouech4853b6d1999-09-22 16:52:47 +00002070 */
2071LPWINE_MLD MMDRV_GetByID(UINT uDevID, UINT type)
2072{
Eric Pouech31a19331999-11-21 00:51:05 +00002073 if (uDevID < llTypes[type].wMaxId)
2074 return &llTypes[type].lpMlds[uDevID];
2075 if ((uDevID == (UINT16)-1 || uDevID == (UINT)-1) && llTypes[type].nMapper != -1)
2076 return &llTypes[type].lpMlds[-1];
2077 return NULL;
Eric Pouech4853b6d1999-09-22 16:52:47 +00002078}
2079
2080/**************************************************************************
2081 * MMDRV_Get [internal]
2082 */
2083LPWINE_MLD MMDRV_Get(HANDLE hndl, UINT type, BOOL bCanBeID)
2084{
2085 LPWINE_MLD mld = NULL;
2086
2087 assert(type < MMDRV_MAX);
2088
2089 if ((UINT)hndl >= llTypes[type].wMaxId) {
2090 mld = (LPWINE_MLD)USER_HEAP_LIN_ADDR(hndl);
2091
Eric Pouech31a19331999-11-21 00:51:05 +00002092 if (!IsBadWritePtr(mld, sizeof(*mld)) && mld->type != type) mld = NULL;
2093 }
2094 if (mld == NULL && bCanBeID) {
Eric Pouech4853b6d1999-09-22 16:52:47 +00002095 mld = MMDRV_GetByID((UINT)hndl, type);
2096 }
2097 return mld;
2098}
2099
2100/**************************************************************************
2101 * MMDRV_GetRelated [internal]
2102 */
2103LPWINE_MLD MMDRV_GetRelated(HANDLE hndl, UINT srcType,
2104 BOOL bSrcCanBeID, UINT dstType)
2105{
2106 LPWINE_MLD mld;
2107
2108 if ((mld = MMDRV_Get(hndl, srcType, bSrcCanBeID)) != NULL) {
2109 WINE_MM_DRIVER_PART* part = &MMDrvs[mld->mmdIndex].parts[dstType];
2110 if (part->nIDMin < part->nIDMax)
2111 return MMDRV_GetByID(part->nIDMin, dstType);
2112 }
2113 return NULL;
2114}
2115
2116/**************************************************************************
2117 * MMDRV_PhysicalFeatures [internal]
2118 */
2119UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1,
2120 DWORD dwParam2)
2121{
2122 WINE_MM_DRIVER* lpDrv = &MMDrvs[mld->mmdIndex];
2123
2124 TRACE("(%p, %04x, %08lx, %08lx)\n", mld, uMsg, dwParam1, dwParam2);
2125
2126 /* all those function calls are undocumented */
2127 switch (uMsg) {
Eric Pouech31a19331999-11-21 00:51:05 +00002128 case 0x801: /* DRV_QUERYDRVENTRY */
Francois Gougetbaa9bf91999-12-27 05:24:06 +00002129 lstrcpynA((LPSTR)dwParam1, lpDrv->name, LOWORD(dwParam2));
Eric Pouech4853b6d1999-09-22 16:52:47 +00002130 break;
Eric Pouech31a19331999-11-21 00:51:05 +00002131 case 0x802: /* DRV_QUERYDEVNODE */
Eric Pouech4853b6d1999-09-22 16:52:47 +00002132 *(LPDWORD)dwParam1 = 0L; /* should be DevNode */
2133 break;
Eric Pouech31a19331999-11-21 00:51:05 +00002134 case 0x803: /* DRV_QUERYNAME */
Eric Pouech4853b6d1999-09-22 16:52:47 +00002135 WARN("NIY 0x803\n");
2136 break;
Eric Pouech31a19331999-11-21 00:51:05 +00002137 case 0x804: /* DRV_QUERYDRIVERIDS */
Eric Pouech4853b6d1999-09-22 16:52:47 +00002138 WARN("NIY call VxD\n");
2139 /* should call VxD MMDEVLDR with (DevNode, dwParam1 and dwParam2) as pmts
2140 * dwParam1 is buffer and dwParam2 is sizeof buffer
2141 * I don't know where the result is stored though
2142 */
2143 break;
Eric Pouech31a19331999-11-21 00:51:05 +00002144 case 0x805: /* DRV_QUERYMAPPABLE */
Eric Pouech4853b6d1999-09-22 16:52:47 +00002145 return (lpDrv->bIsMapper) ? 2 : 0;
Ove Kaavenfd92ebd2000-06-24 12:55:33 +00002146
2147 case 0x810: /* Wine-specific: Retrieve DirectSound interface */
2148 return MMDRV_Message(mld, uMsg, dwParam1, dwParam2, TRUE);
2149
Eric Pouech4853b6d1999-09-22 16:52:47 +00002150 default:
2151 WARN("Unknown call %04x\n", uMsg);
2152 return MMSYSERR_INVALPARAM;
2153 }
2154 return 0L;
2155}
2156
2157/**************************************************************************
2158 * MMDRV_InitPerType [internal]
2159 */
Eric Pouech31655a61999-09-27 13:34:21 +00002160static BOOL MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv, UINT num,
Eric Pouech4853b6d1999-09-22 16:52:47 +00002161 UINT type, UINT wMsg)
2162{
2163 WINE_MM_DRIVER_PART* part = &lpDrv->parts[type];
Eric Pouech31655a61999-09-27 13:34:21 +00002164 DWORD ret;
2165 UINT count = 0;
2166 int i, k;
Eric Pouech4853b6d1999-09-22 16:52:47 +00002167
2168 part->nIDMin = part->nIDMax = 0;
2169
2170 /* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
2171 /* the DRVM_ENABLE is only required when the PnP node is non zero */
2172
2173 if (lpDrv->bIs32 && part->u.fnMessage32) {
2174 ret = part->u.fnMessage32(0, DRVM_INIT, 0L, 0L, 0L);
2175 TRACE("DRVM_INIT => %08lx\n", ret);
2176#if 0
2177 ret = part->u.fnMessage32(0, DRVM_ENABLE, 0L, 0L, 0L);
2178 TRACE("DRVM_ENABLE => %08lx\n", ret);
2179#endif
2180 count = part->u.fnMessage32(0, wMsg, 0L, 0L, 0L);
2181 }
2182
2183 if (!lpDrv->bIs32 && part->u.fnMessage16) {
2184 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2185 0, DRVM_INIT, 0L, 0L, 0L);
2186 TRACE("DRVM_INIT => %08lx\n", ret);
2187#if 0
2188 ret = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2189 0, DRVM_ENABLE, 0L, 0L, 0L);
2190 TRACE("DRVM_ENABLE => %08lx\n", ret);
2191#endif
2192 count = MMDRV_CallTo16_word_wwlll((FARPROC16)part->u.fnMessage16,
2193 0, wMsg, 0L, 0L, 0L);
2194 }
2195
2196 TRACE("Got %u dev for (%s:%s)\n", count, lpDrv->name, llTypes[type].name);
Eric Pouech31655a61999-09-27 13:34:21 +00002197 if (count == 0)
2198 return FALSE;
2199
2200 /* got some drivers */
2201 if (lpDrv->bIsMapper) {
2202 if (llTypes[type].nMapper != -1)
2203 ERR("Two mappers for type %s (%d, %s)\n",
2204 llTypes[type].name, llTypes[type].nMapper, lpDrv->name);
2205 if (count > 1)
2206 ERR("Strange: mapper with %d > 1 devices\n", count);
2207 llTypes[type].nMapper = num;
2208 } else {
2209 part->nIDMin = llTypes[type].wMaxId;
2210 llTypes[type].wMaxId += count;
2211 part->nIDMax = llTypes[type].wMaxId;
Eric Pouech4853b6d1999-09-22 16:52:47 +00002212 }
Eric Pouech31655a61999-09-27 13:34:21 +00002213 TRACE("Setting min=%d max=%d (ttop=%d) for (%s:%s)\n",
2214 part->nIDMin, part->nIDMax, llTypes[type].wMaxId,
2215 lpDrv->name, llTypes[type].name);
2216 /* realloc translation table */
2217 llTypes[type].lpMlds = (LPWINE_MLD)
Alexandre Julliard90476d62000-02-16 22:47:24 +00002218 HeapReAlloc(GetProcessHeap(), 0, (llTypes[type].lpMlds) ? llTypes[type].lpMlds - 1 : NULL,
Eric Pouech31655a61999-09-27 13:34:21 +00002219 sizeof(WINE_MLD) * (llTypes[type].wMaxId + 1)) + 1;
2220 /* re-build the translation table */
2221 if (llTypes[type].nMapper != -1) {
2222 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].name, -1, MMDrvs[llTypes[type].nMapper].name);
Eric Pouech31a19331999-11-21 00:51:05 +00002223 llTypes[type].lpMlds[-1].uDeviceID = (UINT16)-1;
Eric Pouech31655a61999-09-27 13:34:21 +00002224 llTypes[type].lpMlds[-1].type = type;
2225 llTypes[type].lpMlds[-1].mmdIndex = llTypes[type].nMapper;
2226 llTypes[type].lpMlds[-1].dwDriverInstance = 0;
2227 }
2228 for (i = k = 0; i <= num; i++) {
2229 while (MMDrvs[i].parts[type].nIDMin <= k && k < MMDrvs[i].parts[type].nIDMax) {
2230 TRACE("%s:Trans[%d] -> %s\n", llTypes[type].name, k, MMDrvs[i].name);
2231 llTypes[type].lpMlds[k].uDeviceID = k;
2232 llTypes[type].lpMlds[k].type = type;
2233 llTypes[type].lpMlds[k].mmdIndex = i;
2234 llTypes[type].lpMlds[k].dwDriverInstance = 0;
2235 k++;
2236 }
2237 }
2238 return TRUE;
Eric Pouech4853b6d1999-09-22 16:52:47 +00002239}
2240
2241/**************************************************************************
2242 * MMDRV_Install [internal]
2243 */
2244static BOOL MMDRV_Install(LPCSTR name, int num, BOOL bIsMapper)
2245{
2246 int count = 0;
2247 char buffer[128];
2248 HMODULE hModule;
2249 LPWINE_MM_DRIVER lpDrv = &MMDrvs[num];
Eric Pouech4853b6d1999-09-22 16:52:47 +00002250
2251 TRACE("('%s');\n", name);
2252
2253 memset(lpDrv, 0, sizeof(*lpDrv));
2254
2255 /* First load driver */
2256 if ((lpDrv->hDrvr = OpenDriverA(name, 0, 0)) == 0) {
2257 WARN("Couldn't open driver '%s'\n", name);
2258 return FALSE;
2259 }
2260
2261 /* Then look for xxxMessage functions */
2262#define AA(_w,_x,_y,_z) \
2263 func = (WINEMM_msgFunc##_y) _z (hModule, #_x); \
2264 if (func != NULL) \
2265 { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
2266 TRACE("Got %d bit func '%s'\n", _y, #_x); }
2267
Eric Pouech4f81c3e2000-01-15 22:29:32 +00002268 if ((GetDriverFlags(lpDrv->hDrvr) & (WINE_GDF_EXIST|WINE_GDF_16BIT)) == WINE_GDF_EXIST) {
Eric Pouech4853b6d1999-09-22 16:52:47 +00002269 WINEMM_msgFunc32 func;
2270
2271 lpDrv->bIs32 = TRUE;
2272 if ((hModule = GetDriverModuleHandle(lpDrv->hDrvr))) {
2273#define A(_x,_y) AA(_x,_y,32,GetProcAddress)
2274 A(MMDRV_AUX, auxMessage);
2275 A(MMDRV_MIXER, mixMessage);
2276 A(MMDRV_MIDIIN, midMessage);
2277 A(MMDRV_MIDIOUT, modMessage);
2278 A(MMDRV_WAVEIN, widMessage);
2279 A(MMDRV_WAVEOUT, wodMessage);
2280#undef A
2281 }
2282 } else {
2283 WINEMM_msgFunc16 func;
2284
2285 /*
2286 * DESCRIPTION 'wave,aux,mixer:Creative Labs Sound Blaster 16 Driver'
2287 * The beginning of the module description indicates the driver supports
2288 * waveform, auxiliary, and mixer devices. Use one of the following
2289 * device-type names, followed by a colon (:) to indicate the type of
2290 * device your driver supports. If the driver supports more than one
2291 * type of device, separate each device-type name with a comma (,).
2292 *
2293 * wave for waveform audio devices
2294 * wavemapper for wave mappers
2295 * midi for MIDI audio devices
2296 * midimapper for midi mappers
2297 * aux for auxiliary audio devices
2298 * mixer for mixer devices
2299 */
2300
2301 lpDrv->bIs32 = FALSE;
2302 if ((hModule = GetDriverModuleHandle16(lpDrv->hDrvr))) {
2303#define A(_x,_y) AA(_x,_y,16,WIN32_GetProcAddress16)
2304 A(MMDRV_AUX, auxMessage);
2305 A(MMDRV_MIXER, mixMessage);
2306 A(MMDRV_MIDIIN, midMessage);
2307 A(MMDRV_MIDIOUT, modMessage);
2308 A(MMDRV_WAVEIN, widMessage);
2309 A(MMDRV_WAVEOUT, wodMessage);
2310#undef A
2311 }
2312 }
2313#undef AA
2314
2315 if (TRACE_ON(mmsys)) {
2316 if ((lpDrv->bIs32) ? MMDRV_GetDescription32(name, buffer, sizeof(buffer)) :
2317 MMDRV_GetDescription16(name, buffer, sizeof(buffer)))
2318 TRACE("%s => %s\n", name, buffer);
2319 else
2320 TRACE("%s => No description\n", name);
2321 }
2322
2323 if (!count) {
2324 CloseDriver(lpDrv->hDrvr, 0, 0);
2325 WARN("No message functions found\n");
2326 return FALSE;
2327 }
2328
2329 /* FIXME: being a mapper or not should be known by another way */
2330 /* it's known for NE drvs (the description is of the form '*mapper: *'
2331 * I don't have any clue for PE drvs
2332 * on Win 9x, the value is gotten from the key mappable under
2333 * HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\MediaResources\
2334 */
2335 lpDrv->bIsMapper = bIsMapper;
2336 lpDrv->name = HEAP_strdupA(GetProcessHeap(), 0, name);
2337
2338 /* Finish init and get the count of the devices */
2339 MMDRV_InitPerType(lpDrv, num, MMDRV_AUX, AUXDM_GETNUMDEVS);
2340 MMDRV_InitPerType(lpDrv, num, MMDRV_MIXER, MXDM_GETNUMDEVS);
2341 MMDRV_InitPerType(lpDrv, num, MMDRV_MIDIIN, MIDM_GETNUMDEVS);
2342 MMDRV_InitPerType(lpDrv, num, MMDRV_MIDIOUT, MODM_GETNUMDEVS);
2343 MMDRV_InitPerType(lpDrv, num, MMDRV_WAVEIN, WIDM_GETNUMDEVS);
2344 MMDRV_InitPerType(lpDrv, num, MMDRV_WAVEOUT, WODM_GETNUMDEVS);
Eric Pouech31655a61999-09-27 13:34:21 +00002345 /* FIXME: if all those func calls return FALSE, then the driver must be unloaded */
Eric Pouech4853b6d1999-09-22 16:52:47 +00002346 return TRUE;
2347}
2348
2349/**************************************************************************
2350 * MMDRV_Init [internal]
2351 */
2352BOOL MMDRV_Init(void)
2353{
2354 int num = 0;
2355
2356 /* FIXME: this should be moved to init files;
2357 * - either .winerc/wine.conf
2358 * - or made of registry keys
2359 * this is a temporary hack, shall be removed anytime now
2360 */
2361 /* first load hardware drivers */
2362 if (MMDRV_Install("wineoss.drv", num, FALSE)) num++;
2363
2364 /* finish with mappers */
2365 if (MMDRV_Install("msacm.drv", num, TRUE )) num++;
2366 if (MMDRV_Install("midimap.drv", num, TRUE )) num++;
2367
2368
2369 /* be sure that size of MMDrvs matches the max number of loadable drivers !!
2370 * if not just increase size of MMDrvs */
2371 assert(num <= sizeof(MMDrvs)/sizeof(MMDrvs[0]));
2372
2373 return TRUE;
2374}