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