Split driver functions into USER (16 bit part) and WINMM (32 bit part).
[wine] / dlls / winmm / driver.c
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
2
3 /*
4  * WINE Drivers functions
5  *
6  * Copyright 1994 Martin Ayotte
7  * Copyright 1998 Marcus Meissner
8  * Copyright 1999 Eric Pouech
9  */
10
11 #include <string.h>
12 #include "heap.h"
13 #include "windef.h"
14 #include "wingdi.h"
15 #include "winuser.h"
16 #include "mmddk.h"
17 #include "winemm.h"
18 #include "ldt.h"
19 #include "debugtools.h"
20
21 DEFAULT_DEBUG_CHANNEL(driver);
22
23 static LPWINE_DRIVER    lpDrvItemList = NULL;
24
25 /* TODO list :
26  *      - LoadModule count and clean up is not handled correctly (it's not a 
27  *        problem as long as FreeLibrary is not working correctly)
28  */
29
30 /* ### start build ### */
31 extern LONG CALLBACK DRIVER_CallTo16_long_lwwll(FARPROC16,LONG,WORD,WORD,LONG,LONG);
32 /* ### stop build ### */
33
34 /**************************************************************************
35  *                      LoadStartupDrivers                      [internal]
36  */
37 static void WINE_UNUSED DRIVER_LoadStartupDrivers(void)
38 {
39     char        str[256];
40     
41     if (GetPrivateProfileStringA("drivers", NULL, "", str, sizeof(str), "SYSTEM.INI") < 2) {
42         ERR("Can't find drivers section in system.ini\n");
43     } else {
44         HDRVR16 hDrv;
45         LPSTR   ptr;
46
47         for (ptr = str; *ptr; ptr += strlen(ptr) + 1) {
48             TRACE("str='%s'\n", ptr);
49             hDrv = OpenDriver16(ptr, "drivers", 0L);
50             TRACE("hDrv=%04x\n", hDrv);
51         }
52         TRACE("end of list !\n");
53     }
54 }
55
56 /**************************************************************************
57  *                      DRIVER_GetNumberOfModuleRefs            [internal]
58  *
59  * Returns the number of open drivers which share the same module.
60  */
61 static  WORD    DRIVER_GetNumberOfModuleRefs(LPWINE_DRIVER lpNewDrv)
62 {
63     LPWINE_DRIVER       lpDrv;
64     WORD                count = 0;
65
66     if (lpNewDrv->dwFlags & WINE_GDF_16BIT) ERR("OOOch");
67     for (lpDrv = lpDrvItemList; lpDrv; lpDrv = lpDrv->lpNextItem) {
68         if (!(lpDrv->dwFlags & WINE_GDF_16BIT) &&
69             lpDrv->d.d32.hModule == lpNewDrv->d.d32.hModule) {
70             count++;
71         }
72     }
73     return count;
74 }
75
76 /**************************************************************************
77  *                              DRIVER_FindFromHDrvr            [internal]
78  * 
79  * From a hDrvr being 32 bits, returns the WINE internal structure.
80  */
81 LPWINE_DRIVER   DRIVER_FindFromHDrvr(HDRVR hDrvr)
82 {    
83     LPWINE_DRIVER       d = (LPWINE_DRIVER)hDrvr;
84
85     if (hDrvr && HeapValidate(GetProcessHeap(), 0, d) && d->dwMagic == WINE_DI_MAGIC) {
86         return d;
87     }
88     return NULL;
89 }
90
91 /**************************************************************************
92  *                              DRIVER_MapMsg32To16             [internal]
93  *
94  * Map a 32 bit driver message to a 16 bit driver message.
95  *  1 : ok, some memory allocated, need to call DRIVER_UnMapMsg32To16
96  *  0 : ok, no memory allocated
97  * -1 : ko, unknown message
98  * -2 : ko, memory problem
99  */
100 static int DRIVER_MapMsg32To16(WORD wMsg, DWORD* lParam1, DWORD* lParam2)
101 {
102     int ret = -1;
103     
104     switch (wMsg) {
105     case DRV_LOAD:
106     case DRV_ENABLE:
107     case DRV_DISABLE:
108     case DRV_FREE:
109     case DRV_QUERYCONFIGURE:
110     case DRV_REMOVE:
111     case DRV_EXITSESSION:
112     case DRV_EXITAPPLICATION:   
113     case DRV_POWER:
114     case DRV_CLOSE:     /* should be 0/0 */
115     case DRV_OPEN:      /* pass thru */
116         /* lParam1 and lParam2 are not used */
117         ret = 0;
118         break;
119         break;
120     case DRV_CONFIGURE:
121     case DRV_INSTALL:
122         /* lParam1 is a handle to a window (conf) or to a driver (inst) or not used, 
123          * lParam2 is a pointer to DRVCONFIGINFO 
124          */
125         if (*lParam2) {
126             LPDRVCONFIGINFO16   dci16 = (LPDRVCONFIGINFO16)SEGPTR_ALLOC(sizeof(DRVCONFIGINFO16));
127             LPDRVCONFIGINFO     dci32 = (LPDRVCONFIGINFO)(*lParam2);
128             
129             if (dci16) {
130                 LPSTR   str1, str2;
131                 
132                 dci16->dwDCISize = sizeof(DRVCONFIGINFO16);
133                 
134                 if ((str1 = HEAP_strdupWtoA(GetProcessHeap(), 0, dci32->lpszDCISectionName)) != NULL &&
135                     (str2 = SEGPTR_STRDUP(str1)) != NULL) {
136                     dci16->lpszDCISectionName = (LPSTR)SEGPTR_GET(str2);
137                     if (!HeapFree(GetProcessHeap(), 0, str1))
138                         FIXME("bad free line=%d\n", __LINE__);
139                 } else {
140                     return -2;
141                 }
142                 if ((str1 = HEAP_strdupWtoA(GetProcessHeap(), 0, dci32->lpszDCIAliasName)) != NULL &&
143                     (str2 = SEGPTR_STRDUP(str1)) != NULL) {
144                     dci16->lpszDCIAliasName = (LPSTR)SEGPTR_GET(str2);
145                     if (!HeapFree(GetProcessHeap(), 0, str1))
146                         FIXME("bad free line=%d\n", __LINE__);
147                 } else {
148                     return -2;
149                 }
150             } else {
151                 return -2;
152             }
153             *lParam2 = (LPARAM)SEGPTR_GET(dci16);
154             ret = 1;
155         } else {
156             ret = 0;
157         }
158         break;
159     default:
160         if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
161            FIXME("Unknown message 0x%04x\n", wMsg);
162         }
163         ret = 0;
164     }
165     return ret;
166 }
167
168 /**************************************************************************
169  *                              DRIVER_UnMapMsg32To16           [internal]
170  *
171  * UnMap a 32 bit driver message to a 16 bit driver message.
172  *  0 : ok
173  * -1 : ko
174  * -2 : ko, memory problem
175  */
176 static int DRIVER_UnMapMsg32To16(WORD wMsg, DWORD lParam1, DWORD lParam2)
177 {
178     int ret = -1;
179     
180     switch (wMsg) {
181     case DRV_LOAD:
182     case DRV_ENABLE:
183     case DRV_DISABLE:
184     case DRV_FREE:
185     case DRV_QUERYCONFIGURE:
186     case DRV_REMOVE:
187     case DRV_EXITSESSION:
188     case DRV_EXITAPPLICATION:
189     case DRV_POWER:
190     case DRV_OPEN:
191     case DRV_CLOSE:
192         /* lParam1 and lParam2 are not used */
193         break;
194     case DRV_CONFIGURE: 
195     case DRV_INSTALL:
196         /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
197         if (lParam2) {
198             LPDRVCONFIGINFO16   dci16 = (LPDRVCONFIGINFO16)PTR_SEG_TO_LIN(lParam2);
199             
200             if (!SEGPTR_FREE(PTR_SEG_TO_LIN(dci16->lpszDCISectionName)))
201                 FIXME("bad free line=%d\n", __LINE__);
202             if (!SEGPTR_FREE(PTR_SEG_TO_LIN(dci16->lpszDCIAliasName)))
203                 FIXME("bad free line=%d\n", __LINE__);
204             if (!SEGPTR_FREE(dci16))
205                 FIXME("bad free line=%d\n", __LINE__);
206         }
207         ret = 0;
208         break;
209     default:
210         if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
211             FIXME("Unknown message 0x%04x\n", wMsg);
212         }
213         ret = 0;
214     }
215     return ret;
216 }
217
218 /**************************************************************************
219  *                              DRIVER_SendMessage              [internal]
220  */
221 static LRESULT inline DRIVER_SendMessage(LPWINE_DRIVER lpDrv, UINT msg, 
222                                         LPARAM lParam1, LPARAM lParam2)
223 {
224     if (lpDrv->dwFlags & WINE_GDF_16BIT) {
225         LRESULT         ret;
226         int             map = 0;
227         TRACE("Before sdm16 call hDrv=%04x wMsg=%04x p1=%08lx p2=%08lx\n", 
228               lpDrv->d.d16.hDriver16, msg, lParam1, lParam2);
229
230         if ((map = DRIVER_MapMsg32To16(msg, &lParam1, &lParam2)) >= 0) {
231             ret = SendDriverMessage16(lpDrv->d.d16.hDriver16, msg, lParam1, lParam2);
232             if (map == 1)
233                 DRIVER_UnMapMsg32To16(msg, lParam1, lParam2);
234         } else {
235             ret = 0;
236         }
237         return ret;
238     }
239     TRACE("Before func32 call proc=%p driverID=%08lx hDrv=%08x wMsg=%04x p1=%08lx p2=%08lx\n", 
240           lpDrv->d.d32.lpDrvProc, lpDrv->d.d32.dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2);
241     return lpDrv->d.d32.lpDrvProc(lpDrv->d.d32.dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2);
242 }
243
244 /**************************************************************************
245  *                              SendDriverMessage               [WINMM.19]
246  */
247 LRESULT WINAPI SendDriverMessage(HDRVR hDriver, UINT msg, LPARAM lParam1,
248                                  LPARAM lParam2)
249 {
250     LPWINE_DRIVER       lpDrv;
251     LRESULT             retval = 0;
252     
253     TRACE("(%04x, %04X, %08lX, %08lX)\n", hDriver, msg, lParam1, lParam2);
254     
255     if ((lpDrv = DRIVER_FindFromHDrvr(hDriver)) != NULL) {
256         retval = DRIVER_SendMessage(lpDrv, msg, lParam1, lParam2);
257     } else {
258         WARN("Bad driver handle %u\n", hDriver);
259     }
260     TRACE("retval = %ld\n", retval);
261     
262     return retval;
263 }
264
265 /**************************************************************************
266  *                              DRIVER_RemoveFromList           [internal]
267  *
268  * Generates all the logic to handle driver closure / deletion
269  * Removes a driver struct to the list of open drivers.
270  */
271 static  BOOL    DRIVER_RemoveFromList(LPWINE_DRIVER lpDrv)
272 {
273     if (!(lpDrv->dwFlags & WINE_GDF_16BIT)) {
274         if (DRIVER_GetNumberOfModuleRefs(lpDrv) == 1) {
275             DRIVER_SendMessage(lpDrv, DRV_DISABLE, 0L, 0L);
276             DRIVER_SendMessage(lpDrv, DRV_FREE,    0L, 0L);
277         }
278     }
279     
280     if (lpDrv->lpPrevItem)
281         lpDrv->lpPrevItem->lpNextItem = lpDrv->lpNextItem;
282     else
283         lpDrvItemList = lpDrv->lpNextItem;
284     if (lpDrv->lpNextItem)
285         lpDrv->lpNextItem->lpPrevItem = lpDrv->lpPrevItem;
286
287     return TRUE;
288 }
289
290 /**************************************************************************
291  *                              DRIVER_AddToList                [internal]
292  *
293  * Adds a driver struct to the list of open drivers.
294  * Generates all the logic to handle driver creation / open.
295  */
296 static  BOOL    DRIVER_AddToList(LPWINE_DRIVER lpNewDrv, LPARAM lParam1, LPARAM lParam2)
297 {
298     lpNewDrv->dwMagic = WINE_DI_MAGIC;
299     /* First driver to be loaded for this module, need to load correctly the module */
300     if (!(lpNewDrv->dwFlags & WINE_GDF_16BIT)) {
301         if (DRIVER_GetNumberOfModuleRefs(lpNewDrv) == 0) {
302             if (DRIVER_SendMessage(lpNewDrv, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) {
303                 TRACE("DRV_LOAD failed on driver 0x%08lx\n", (DWORD)lpNewDrv);
304                 return FALSE;
305             }
306             /* returned value is not checked */
307             DRIVER_SendMessage(lpNewDrv, DRV_ENABLE, 0L, 0L);
308         }
309     }
310
311     lpNewDrv->lpNextItem = NULL;
312     if (lpDrvItemList == NULL) {
313         lpDrvItemList = lpNewDrv;
314         lpNewDrv->lpPrevItem = NULL;
315     } else {
316         LPWINE_DRIVER   lpDrv = lpDrvItemList;  /* find end of list */
317         while (lpDrv->lpNextItem != NULL)
318             lpDrv = lpDrv->lpNextItem;
319         
320         lpDrv->lpNextItem = lpNewDrv;
321         lpNewDrv->lpPrevItem = lpDrv;
322     }
323
324     if (!(lpNewDrv->dwFlags & WINE_GDF_16BIT)) {
325         /* Now just open a new instance of a driver on this module */
326         lpNewDrv->d.d32.dwDriverID = DRIVER_SendMessage(lpNewDrv, DRV_OPEN, lParam1, lParam2);
327
328         if (lpNewDrv->d.d32.dwDriverID == 0) {
329             TRACE("DRV_OPEN failed on driver 0x%08lx\n", (DWORD)lpNewDrv);
330             DRIVER_RemoveFromList(lpNewDrv);
331             return FALSE;
332         }
333     }
334     return TRUE;
335 }
336
337 /**************************************************************************
338  *                              DRIVER_GetLibName               [internal]
339  *
340  */
341 BOOL    DRIVER_GetLibName(LPCSTR keyName, LPCSTR sectName, LPSTR buf, int sz)
342 {
343     /* should also do some registry diving */
344     return GetPrivateProfileStringA(sectName, keyName, "", buf, sz, "SYSTEM.INI");
345 }
346
347 /**************************************************************************
348  *                              DRIVER_TryOpenDriver32          [internal]
349  *
350  * Tries to load a 32 bit driver whose DLL's (module) name is fn
351  */
352 LPWINE_DRIVER   DRIVER_TryOpenDriver32(LPCSTR fn, LPARAM lParam2)
353 {
354     LPWINE_DRIVER       lpDrv = NULL;
355     HMODULE             hModule = 0;
356     LPSTR               ptr;
357     LPCSTR              cause = 0;
358
359     TRACE("('%s', %08lX);\n", fn, lParam2);
360     
361     if ((ptr = strchr(fn, ' ')) != NULL) {
362         *ptr++ = '\0';
363         while (*ptr == ' ') ptr++;
364         if (*ptr == '\0') ptr = NULL;
365     }
366
367     lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER));
368     if (lpDrv == NULL) {cause = "OOM"; goto exit;}
369
370     if ((hModule = LoadLibraryA(fn)) == 0) {cause = "Not a 32 bit lib"; goto exit;}
371
372     lpDrv->d.d32.lpDrvProc = GetProcAddress(hModule, "DriverProc");
373     if (lpDrv->d.d32.lpDrvProc == NULL) {cause = "no DriverProc"; goto exit;}
374
375     lpDrv->dwFlags          = 0;
376     lpDrv->d.d32.hModule    = hModule;
377     lpDrv->d.d32.dwDriverID = 0;
378
379     if (!DRIVER_AddToList(lpDrv, (LPARAM)ptr, lParam2)) {cause = "load faile"; goto exit;}
380
381     TRACE("=> %p\n", lpDrv);
382     return lpDrv;
383  exit:
384     FreeLibrary(hModule);
385     HeapFree(GetProcessHeap(), 0, lpDrv);
386     TRACE("Unable to load 32 bit module \"%s\": %s\n", fn, cause);
387     return NULL;
388 }
389
390 /**************************************************************************
391  *                              DRIVER_TryOpenDriver16          [internal]
392  *
393  * Tries to load a 16 bit driver whose DLL's (module) name is lpFileName.
394  */
395 static  LPWINE_DRIVER   DRIVER_TryOpenDriver16(LPCSTR fn, LPCSTR sn, LPARAM lParam2)
396 {
397     LPWINE_DRIVER       lpDrv = NULL;
398     LPCSTR              cause = 0;
399
400     TRACE("('%s', %08lX);\n", sn, lParam2);
401     
402     lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER));
403     if (lpDrv == NULL) {cause = "OOM"; goto exit;}
404
405     /* FIXME: shall we do some black magic here on sn ?
406      *  drivers32 => drivers
407      *  mci32 => mci
408      * ...
409      */
410     lpDrv->d.d16.hDriver16 = OpenDriver16(fn, sn, lParam2);
411     if (lpDrv->d.d16.hDriver16 == 0) {cause = "Not a 16 bit driver"; goto exit;}
412     lpDrv->dwFlags = WINE_GDF_16BIT;
413
414     if (!DRIVER_AddToList(lpDrv, 0, lParam2)) {cause = "load faile"; goto exit;}
415
416     TRACE("=> %p\n", lpDrv);
417     return lpDrv;
418  exit:
419     HeapFree(GetProcessHeap(), 0, lpDrv);
420     TRACE("Unable to load 32 bit module \"%s\": %s\n", fn, cause);
421     return NULL;
422 }
423
424 /**************************************************************************
425  *                              OpenDriverA                     [WINMM.15]
426  * (0,1,DRV_LOAD  ,0       ,0)
427  * (0,1,DRV_ENABLE,0       ,0)
428  * (0,1,DRV_OPEN  ,buf[256],0)
429  */
430 HDRVR WINAPI OpenDriverA(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam2) 
431 {
432     LPWINE_DRIVER       lpDrv = NULL;
433     char                libName[128];
434     LPCSTR              lsn = lpSectionName;
435
436     TRACE("(%s, %s, 0x%08lx);\n", debugstr_a(lpDriverName), debugstr_a(lpSectionName), lParam2);
437     
438     if (lsn == NULL) {
439         lstrcpynA(libName, lpDriverName, sizeof(libName));
440
441         if ((lpDrv = DRIVER_TryOpenDriver32(libName, lParam2)))
442             goto the_end;
443         lsn = "Drivers32";
444     }
445     if (DRIVER_GetLibName(lpDriverName, lsn, libName, sizeof(libName)) &&
446         (lpDrv = DRIVER_TryOpenDriver32(libName, lParam2)))
447         goto the_end;
448
449     if (!(lpDrv = DRIVER_TryOpenDriver16(lpDriverName, lpSectionName, lParam2)))
450         ERR("Failed to open driver %s from section %s\n", lpDriverName, lpSectionName);
451  the_end:
452     if (lpDrv)  TRACE("=> %08lx\n", (DWORD)lpDrv);
453     return (DWORD)lpDrv;
454 }
455
456 /**************************************************************************
457  *                              OpenDriverW                     [WINMM.15]
458  */
459 HDRVR WINAPI OpenDriverW(LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lParam)
460 {
461     LPSTR               dn = HEAP_strdupWtoA(GetProcessHeap(), 0, lpDriverName);
462     LPSTR               sn = HEAP_strdupWtoA(GetProcessHeap(), 0, lpSectionName);
463     HDRVR               ret = OpenDriverA(dn, sn, lParam);
464     
465     if (dn) HeapFree(GetProcessHeap(), 0, dn);
466     if (sn) HeapFree(GetProcessHeap(), 0, sn);
467     return ret;
468 }
469
470 /**************************************************************************
471  *                      CloseDriver                             [WINMM.4]
472  */
473 LRESULT WINAPI CloseDriver(HDRVR hDrvr, LPARAM lParam1, LPARAM lParam2)
474 {
475     LPWINE_DRIVER       lpDrv;
476
477     TRACE("(%04x, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
478     
479     if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
480         if (lpDrv->dwFlags & WINE_GDF_16BIT)
481             CloseDriver16(lpDrv->d.d16.hDriver16, lParam1, lParam2);
482         else
483             DRIVER_SendMessage(lpDrv, DRV_CLOSE, lParam1, lParam2);
484         if (DRIVER_RemoveFromList(lpDrv)) {
485             HeapFree(GetProcessHeap(), 0, lpDrv);
486             return TRUE;
487         }
488     }
489     WARN("Failed to close driver\n");
490     return FALSE;
491 }
492
493 /**************************************************************************
494  *                              GetDriverFlags          [WINMM.13]
495  * [in] hDrvr handle to the driver
496  *
497  * Returns:
498  *      0x00000000 if hDrvr is an invalid handle
499  *      0x80000000 if hDrvr is a valid 32 bit driver
500  *      0x90000000 if hDrvr is a valid 16 bit driver
501  *
502  * native WINMM doesn't return those flags
503  *      0x80000000 for a valid 32 bit driver and that's it
504  *      (I may have mixed up the two flags :-(
505  */
506 DWORD   WINAPI GetDriverFlags(HDRVR hDrvr)
507 {
508     LPWINE_DRIVER       lpDrv;
509     DWORD               ret = 0;
510
511     TRACE("(%04x)\n", hDrvr);
512
513     if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
514         ret = WINE_GDF_EXIST | lpDrv->dwFlags;
515     }
516     return ret;
517 }
518
519 /**************************************************************************
520  *                              GetDriverModuleHandle   [WINMM.14]
521  */
522 HMODULE WINAPI GetDriverModuleHandle(HDRVR hDrvr)
523 {
524     LPWINE_DRIVER       lpDrv;
525     HMODULE             hModule = 0;
526     
527     TRACE("(%04x);\n", hDrvr);
528     
529     if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
530         if (!(lpDrv->dwFlags & WINE_GDF_16BIT))
531             hModule = lpDrv->d.d32.hModule;
532     }
533     TRACE("=> %04x\n", hModule);
534     return hModule;
535 }
536
537 /**************************************************************************
538  *                              DrvOpen                 [MMSYSTEM.1100]
539  */
540 HDRVR16 WINAPI DrvOpen16(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
541 {
542     return OpenDriver16(lpDriverName, lpSectionName, lParam);
543 }
544
545 /**************************************************************************
546  *                              DrvClose                [MMSYSTEM.1101]
547  */
548 LRESULT WINAPI DrvClose16(HDRVR16 hDrv, LPARAM lParam1, LPARAM lParam2)
549 {
550     return CloseDriver16(hDrv, lParam1, lParam2);
551 }
552
553 /**************************************************************************
554  *                              DrvSendMessage          [MMSYSTEM.1102]
555  */
556 LRESULT WINAPI DrvSendMessage16(HDRVR16 hDrv, WORD msg, LPARAM lParam1,
557                                 LPARAM lParam2)
558 {
559     return SendDriverMessage16(hDrv, msg, lParam1, lParam2);
560 }
561
562 /**************************************************************************
563  *                              DrvGetModuleHandle      [MMSYSTEM.1103]
564  */
565 HANDLE16 WINAPI DrvGetModuleHandle16(HDRVR16 hDrv)
566 {
567     return GetDriverModuleHandle16(hDrv);
568 }
569
570 /**************************************************************************
571  *                              DrvDefDriverProc        [MMSYSTEM.1104]
572  */
573 LRESULT WINAPI DrvDefDriverProc16(DWORD dwDriverID, HDRVR16 hDrv, WORD wMsg, 
574                                   DWORD dwParam1, DWORD dwParam2)
575 {
576     return DefDriverProc16(dwDriverID, hDrv, wMsg, dwParam1, dwParam2);
577 }
578
579 /**************************************************************************
580  *                              DefDriverProc                     [WINMM.5]
581  */
582 LRESULT WINAPI DefDriverProc(DWORD dwDriverIdentifier, HDRVR hDrv,
583                              UINT Msg, LPARAM lParam1, LPARAM lParam2)
584 {
585     switch (Msg) {
586     case DRV_LOAD:
587     case DRV_FREE:
588     case DRV_ENABLE:
589     case DRV_DISABLE:
590         return 1;
591     case DRV_INSTALL:
592     case DRV_REMOVE:
593         return DRV_SUCCESS;
594     default:
595         return 0;
596     }
597 }
598
599 /**************************************************************************
600  *                              DriverProc                      [MMSYSTEM.6]
601  */
602 LRESULT WINAPI DriverProc16(DWORD dwDevID, HDRVR16 hDrv, WORD wMsg, 
603                             DWORD dwParam1, DWORD dwParam2)
604 {
605     TRACE("dwDevID=%08lx hDrv=%04x wMsg=%04x dwParam1=%08lx dwParam2=%08lx\n",
606           dwDevID, hDrv, wMsg, dwParam1, dwParam2);
607
608     return DrvDefDriverProc16(dwDevID, hDrv, wMsg, dwParam1, dwParam2);
609 }
610