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