source: trunk/src/winmm/driver.cpp@ 4748

Last change on this file since 4748 was 4748, checked in by sandervl, 25 years ago

CW: Ported Wine MCI code

File size: 18.5 KB
Line 
1/* $Id: driver.cpp,v 1.7 2000-12-03 22:18:17 sandervl Exp $ */
2
3/*
4 * Driver multimedia apis
5 *
6 * Copyright 1994 Martin Ayotte
7 * Copyright 1998 Marcus Meissner
8 * Copyright 1998 Patrick Haller
9 * Copyright 1998/1999 Eric Pouech
10 * Copyright 2000 Chris Wohlgemuth
11 *
12 * Project Odin Software License can be found in LICENSE.TXT
13 *
14 */
15
16
17/****************************************************************************
18 * Includes *
19 ****************************************************************************/
20
21#include <os2win.h>
22#include <odinwrap.h>
23#include <string.h>
24#include <misc.h>
25#include <unicode.h>
26
27#include "os2timer.h"
28
29#define DBG_LOCALLOG DBG_driver
30#include "dbglocal.h"
31
32
33/* Who said goofy boy ? */
34#define WINE_DI_MAGIC 0x900F1B01
35
36typedef struct tagWINE_DRIVER
37{
38 DWORD dwMagic;
39 char szAliasName[128];
40 /* as usual LPWINE_DRIVER == hDriver32 */
41 HDRVR16 hDriver16;
42 union {
43 struct {
44 HMODULE16 hModule;
45 DRIVERPROC16 lpDrvProc;
46 } d16;
47 struct {
48 HMODULE hModule;
49 DRIVERPROC lpDrvProc;
50 } d32;
51 } d;
52 DWORD dwDriverID;
53 DWORD dwFlags;
54 struct tagWINE_DRIVER* lpPrevItem;
55 struct tagWINE_DRIVER* lpNextItem;
56} WINE_DRIVER, *LPWINE_DRIVER;
57
58static LPWINE_DRIVER DRIVER_RegisterDriver32(LPCSTR, HMODULE, DRIVERPROC, LPARAM, BOOL);
59
60static LPWINE_DRIVER lpDrvItemList = NULL;
61
62/* TODO list :
63 * WINE remark: - LoadModule count and clean up is not handled correctly (it's not a
64 * problem as long as FreeLibrary is not working correctly)
65 * - shoudln't the allocations be done on a per process basis ?
66 */
67
68static HDRVR DRIVER_OpenDriverA(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam) ;
69static LPWINE_DRIVER DRIVER_FindFromHDrvr(HDRVR hDrvr);
70static BOOL DRIVER_CloseDriver(LPWINE_DRIVER lpDrv, DWORD lParam1, DWORD lParam2);
71
72ODINDEBUGCHANNEL(WINMM-DRIVER)
73
74
75/*****************************************************************************
76 * Sends the specifiedmessage to the installable driver
77 * Parameters: HDRVR hDrvr
78 * UINT msg
79 * LONG lParam1
80 * LONG lParam2
81 * Variables :
82 * @return : API returncode
83 * Remark :
84 * @status : Completely
85 *
86 * @author : Patrick Haller [Tue, 1998/05/05 10:44]
87 * @author : Chris Wohlgemuth [Sun, 2000/11/19]
88 *****************************************************************************/
89
90ODINFUNCTION4(LRESULT, SendDriverMessage,
91 HDRVR, hdrvr,
92 UINT, msg,
93 LONG, lParam1,
94 LONG, lParam2)
95{
96 LPWINE_DRIVER lpDrv;
97 LRESULT retval = 0;
98
99 dprintf(("Entering SendDriverMessage (%04x, %04X, %08lX, %08lX)\n", hdrvr, msg, lParam1, lParam2));
100
101 lpDrv = DRIVER_FindFromHDrvr(hdrvr);
102
103 if (lpDrv != NULL) {
104 if (lpDrv->dwFlags & WINE_GDF_16BIT) {
105#if 0
106 /*We don't use 16 bit */
107 mapRet = DRIVER_MapMsg32To16(msg, &lParam1, &lParam2);
108 if (mapRet >= 0) {
109 TRACE("Before CallDriverProc proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
110 lpDrv->d.d16.lpDrvProc, lpDrv->dwDriverID, lpDrv->hDriver16, msg, lParam1, lParam2);
111 retval = DRIVER_CallTo16_long_lwwll((FARPROC16)lpDrv->d.d16.lpDrvProc, lpDrv->dwDriverID,
112 lpDrv->hDriver16, msg, lParam1, lParam2);
113 if (mapRet >= 1) {
114 DRIVER_UnMapMsg32To16(msg, lParam1, lParam2);
115 }
116 } else {
117 retval = 0;
118 }
119#endif
120 } else {
121
122#if 0
123 dprintf(("Before func32 call proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
124 lpDrv->d.d32.lpDrvProc, lpDrv->dwDriverID, hdrvr, msg, lParam1, lParam2));
125#endif
126
127 retval = lpDrv->d.d32.lpDrvProc(lpDrv->dwDriverID, hdrvr, msg, lParam1, lParam2);
128 }
129 } else {
130 dprintf(("Bad driver handle %u\n", hdrvr));
131 }
132
133 dprintf(("(SendDriverMessage) Driver proc returned retval = %ld (0x%lx)\n", retval, retval));
134
135 return retval;
136}
137
138
139/*****************************************************************************
140 * Opens an instance of an installable driver and initializes
141 * the instance using either the driver's default settings or a
142 * driver-specific value.
143 * Parameters: LPCWSTR lpDriverName
144 * LPCWSTR lpSectionName
145 * LONG lParam
146 * Variables :
147 * @return : API returncode
148 * Remark :
149 * @status : Stub
150 *
151 * @author : Patrick Haller [Tue, 1998/05/05 10:44]
152 *****************************************************************************/
153
154ODINFUNCTION3(HDRVR, OpenDriver,
155 LPCWSTR, lpDriverName,
156 LPCWSTR, lpSectionName,
157 LONG, lParam)
158{
159 dprintf(("WINMM: OpenDriver not implemented.\n"));
160 return 0; /* unsuccessful return */
161}
162
163
164/*****************************************************************************
165 * Opens an instance of an installable driver and initializes
166 * the instance using either the driver's default settings or a
167 * driver-specific value.
168 * Parameters: LPCTSTR lpDriverName
169 * LPCTSTR lpSectionName
170 * LONG lParam
171 * Variables :
172 * @return : API returncode
173 * Remark :
174 * @status : Partially tested
175 *
176 * @author : Patrick Haller [Tue, 1998/05/05 10:44]
177 *****************************************************************************/
178
179ODINFUNCTION3(HDRVR, OpenDriverA,
180 LPCSTR, lpDriverName,
181 LPCSTR, lpSectionName,
182 LONG, lParam)
183{
184 return DRIVER_OpenDriverA(lpDriverName, lpSectionName, lParam);
185 // return 0; /* unsuccessful return */
186}
187
188
189
190/*****************************************************************************
191 * Closes an installable driver.
192 * Parameters: HDRVR hDrvr
193 * LONG lParam1
194 * LONG lParam2
195 * Variables :
196 * @return :
197 * Remark :
198 * @status : Partially tested
199 *
200 * @author : Patrick Haller [Tue, 1998/05/05 10:44]
201 *****************************************************************************/
202
203ODINFUNCTION3(LRESULT, CloseDriver,
204 HDRVR, hDrvr,
205 LONG, lParam1,
206 LONG, lParam2)
207{
208 return DRIVER_CloseDriver(DRIVER_FindFromHDrvr(hDrvr), lParam1, lParam2);//return 0; /* unsuccessful return */
209}
210
211
212/*****************************************************************************
213 * Provides default processing for anymessages not processed by
214 * an installable driver.
215 * Parameters: DWORD dwDriverID
216 * HDRVR hDrvr
217 * UINT msg
218 * LONG lParam1
219 * LONG lParam2
220 * Variables :
221 * @return :
222 * Remark :
223 * @status : Partially
224 *
225 * @author : Patrick Haller [Tue, 1998/05/05 10:44]
226 * @author : Chris Wohlgemuth [Sun, 2000/11/19]
227 *****************************************************************************/
228
229ODINFUNCTION5(LRESULT, DefDriverProc,
230 DWORD, dwDriverID,
231 HDRVR, hDrvr,
232 UINT, msg,
233 LONG, lParam1,
234 LONG, lParam2)
235{
236 switch (msg) {
237 case DRV_LOAD:
238 case DRV_FREE:
239 case DRV_ENABLE:
240 case DRV_DISABLE:
241 // return 1;
242 case DRV_INSTALL:
243 case DRV_REMOVE:
244 // return DRV_SUCCESS;
245 default:
246 return 0; /* unsuccessful return */
247 }
248
249}
250
251
252/*****************************************************************************
253 * Parameters: DWORD dwCallback
254 * DWORD dwFlags
255 * HDRVR hDrvr
256 * DWORD msg
257 * DWORD dwUser
258 * DWORD dwParam1
259 * DWORD dwParam2
260 * Variables :
261 * @return :
262 * Remark :
263 * @status : Stub
264 *
265 * @author : Patrick Haller [Tue, 1998/05/05 10:44]
266 *****************************************************************************/
267
268ODINFUNCTION7(LRESULT, DriverCallback,
269 DWORD, dwCallback,
270 DWORD, dwFlags,
271 HDRVR, hDrvr,
272 DWORD, msg,
273 DWORD, dwUser,
274 DWORD, dwParam1,
275 DWORD, dwParam2)
276{
277 dprintf(("WINMM: DriverCallback not implemented.\n"));
278 return FALSE; /* unsuccessful return */
279}
280
281
282/*****************************************************************************
283 * Purpose : Retrieves the instance handle of the module that contains the
284 * installable driver.
285 * Parameters: HDRVR hDriver
286 * Variables :
287 * @return :
288 * Remark :
289 * @status : Stub
290 *
291 * @author : Patrick Haller [Tue, 1998/05/05 10:44]
292 *****************************************************************************/
293
294ODINFUNCTION1(HMODULE, DrvGetModuleHandle,
295 HDRVR, hDriver)
296{
297 dprintf(("WINMM: DrvGetModuleHandle not implemented.\n"));
298 return 0; /* unsuccessful return */
299}
300
301
302/*****************************************************************************
303 * Sends the specified message to the installable driver
304 * Parameters: HDRVR hDrvr
305 * UINT msg
306 * LONG lParam1
307 * LONG lParam2
308 * Variables :
309 * @return : API returncode
310 * Remark : Ehm, what's the difference to SendDriverMessage() ?
311 * @status : Stub
312 *
313 * @author : Patrick Haller [Tue, 1998/05/05 10:44]
314 *****************************************************************************/
315
316ODINFUNCTION4(LRESULT, DrvSendMessage,
317 HDRVR, hdrvr,
318 UINT, msg,
319 LONG, lParam1,
320 LONG, lParam2)
321{
322 dprintf(("WINMM: DrvSendMessage not implemented.\n"));
323 return 0; /* unsuccessful return */
324}
325
326
327/*****************************************************************************
328 * Retrieves the instance handle of the module that contains the
329 * installable driver.
330 * Parameters: HDRVR hDriver
331 * Variables :
332 * @return :
333 * Remark : What's the difference to DrvGetModuleHandle() ?
334 * @status : Completely
335 *
336 * @author : Patrick Haller [Tue, 1998/05/05 10:44]
337 * @author : Chris Wohlgemuth [Sun, 2000/11/19]
338 *****************************************************************************/
339
340ODINFUNCTION1(HMODULE, GetDriverModuleHandle,
341 HDRVR, hDriver)
342{
343 LPWINE_DRIVER lpDrv;
344 HMODULE hModule = 0;
345
346#if 0
347 dprintf(("(%04x);\n", hDriver));
348#endif
349
350 lpDrv = DRIVER_FindFromHDrvr(hDriver);
351 if (lpDrv != NULL && !(lpDrv->dwFlags & WINE_GDF_16BIT)) {
352 hModule = lpDrv->d.d32.hModule;
353
354}
355#if 0
356 dprintf(("=> %d\n", hModule));
357#endif
358 return hModule; //return 0; /* unsuccessful return */
359}
360
361
362
363/**************************************************************************
364 * GetDriverFlags [WINMM.13]
365 * Parameters: HDRVR hDrvr
366 * Variables :
367 * @return : 0x00000000 if hDrvr is an invalid handle
368 * 0x80000000 if hDrvr is a valid 32 bit driver
369 * Remark :
370 * @status : Completely
371 *
372 * @author : Chris Wohlgemuth [Sun, 2000/11/19] (ported from WINE)
373 */
374ODINFUNCTION1(DWORD, GetDriverFlags,
375 HDRVR, hDrvr)
376{
377 LPWINE_DRIVER lpDrv;
378 DWORD ret = 0;
379
380 //TRACE("(%04x)\n", hDrvr);
381
382 if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
383 ret = lpDrv->dwFlags;
384 }
385 return ret;
386}
387
388
389/**************************************************************************/
390/* Implementation */
391/**************************************************************************/
392
393/**************************************************************************
394 * DRIVER_GetNumberOfModuleRefs [internal]
395 *
396 * Returns the number of open drivers which share the same module.
397 */
398static WORD DRIVER_GetNumberOfModuleRefs(LPWINE_DRIVER lpNewDrv)
399{
400 LPWINE_DRIVER lpDrv;
401 WORD count = 0;
402
403 for (lpDrv = lpDrvItemList; lpDrv; lpDrv = lpDrv->lpNextItem) {
404 if (lpDrv->dwFlags & WINE_GDF_16BIT) {
405 if (lpDrv->d.d16.hModule == lpNewDrv->d.d16.hModule) {
406 count++;
407 }
408 } else {
409 if (lpDrv->d.d32.hModule == lpNewDrv->d.d32.hModule) {
410 count++;
411 }
412 }
413 }
414 return count;
415}
416
417
418/**************************************************************************
419 * DRIVER_FindFromHDrvr [internal]
420 *
421 * From a hDrvr (being 16 or 32 bits), returns the WINE internal structure.
422 */
423static LPWINE_DRIVER DRIVER_FindFromHDrvr(HDRVR hDrvr)
424{
425 if (!IsBadWritePtr((void*)hDrvr, sizeof(WINE_DRIVER)) &&
426 ((LPWINE_DRIVER)hDrvr)->dwMagic == WINE_DI_MAGIC) {
427 return (LPWINE_DRIVER)hDrvr;
428 }
429 return 0;
430}
431
432/**************************************************************************
433 * DRIVER_RemoveFromList [internal]
434 *
435 * Generates all the logic to handle driver closure / deletion
436 * Removes a driver struct to the list of open drivers.
437 *
438 */
439static BOOL DRIVER_RemoveFromList(LPWINE_DRIVER lpDrv)
440{
441 lpDrv->dwDriverID = 0;
442 if (DRIVER_GetNumberOfModuleRefs(lpDrv) == 1) {
443 SendDriverMessage((HDRVR)lpDrv, DRV_DISABLE, 0L, 0L);
444 SendDriverMessage((HDRVR)lpDrv, DRV_FREE, 0L, 0L);
445 }
446
447 if (lpDrv->lpPrevItem)
448 lpDrv->lpPrevItem->lpNextItem = lpDrv->lpNextItem;
449 else
450 lpDrvItemList = lpDrv->lpNextItem;
451 if (lpDrv->lpNextItem)
452 lpDrv->lpNextItem->lpPrevItem = lpDrv->lpPrevItem;
453
454 return TRUE;
455}
456
457/**************************************************************************
458 * DRIVER_AddToList [internal]
459 *
460 * Adds a driver struct to the list of open drivers.
461 * Generates all the logic to handle driver creation / open.
462 *
463 */
464static BOOL DRIVER_AddToList(LPWINE_DRIVER lpNewDrv, LPARAM lParam, BOOL bCallFrom32)
465{
466 lpNewDrv->dwMagic = WINE_DI_MAGIC;
467 /* First driver to be loaded for this module, need to load correctly the module */
468
469 if (DRIVER_GetNumberOfModuleRefs(lpNewDrv) == 0) {
470 if (SendDriverMessage((HDRVR)lpNewDrv, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) {
471 dprintf(("DRV_LOAD failed on driver 0x%08lx\n", (DWORD)lpNewDrv));
472 return FALSE;
473 }
474 if (SendDriverMessage((HDRVR)lpNewDrv, DRV_ENABLE, 0L, 0L) != DRV_SUCCESS) {
475 dprintf(("DRV_ENABLE failed on driver 0x%08lx\n", (DWORD)lpNewDrv));
476 return FALSE;
477 }
478 }
479
480 lpNewDrv->lpNextItem = NULL;
481 if (lpDrvItemList == NULL) {
482 lpDrvItemList = lpNewDrv;
483 lpNewDrv->lpPrevItem = NULL;
484 } else {
485 LPWINE_DRIVER lpDrv = lpDrvItemList; /* find end of list */
486 while (lpDrv->lpNextItem != NULL)
487 lpDrv = lpDrv->lpNextItem;
488
489 lpDrv->lpNextItem = lpNewDrv;
490 lpNewDrv->lpPrevItem = lpDrv;
491 }
492 /* Now just open a new instance of a driver on this module */
493
494 lpNewDrv->dwDriverID = SendDriverMessage((HDRVR)lpNewDrv, DRV_OPEN, 0L, lParam);
495
496 if (lpNewDrv->dwDriverID == 0) {
497 dprintf(("DRV_OPEN failed on driver 0x%08lx\n", (DWORD)lpNewDrv));
498 DRIVER_RemoveFromList(lpNewDrv);
499 return FALSE;
500 }
501
502 return TRUE;
503}
504
505/**************************************************************************
506 * DRIVER_RegisterDriver32 [internal]
507 *
508 * Creates all the WINE internal representations for a 32 bit driver.
509 * The driver is also open by sending the correct messages.
510 *
511 */
512static LPWINE_DRIVER DRIVER_RegisterDriver32(LPCSTR lpName, HMODULE hModule, DRIVERPROC lpProc,
513 LPARAM lParam, BOOL bCallFrom32)
514{
515 LPWINE_DRIVER lpDrv;
516
517 lpDrv = (LPWINE_DRIVER)HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER));
518 if (lpDrv != NULL) {
519 lpDrv->dwFlags = WINE_GDF_EXIST;
520 lpDrv->dwDriverID = 0;
521 lpDrv->hDriver16 = 0; /* We don't support 16 bit */
522 lstrcpynA(lpDrv->szAliasName, lpName, sizeof(lpDrv->szAliasName));
523 lpDrv->d.d32.hModule = hModule;
524 lpDrv->d.d32.lpDrvProc = lpProc;
525
526 if (!DRIVER_AddToList(lpDrv, lParam, bCallFrom32)) {
527 HeapFree(GetProcessHeap(), 0, lpDrv);
528 lpDrv = NULL;
529 }
530
531 }
532 return lpDrv;
533}
534
535/**************************************************************************
536 * DRIVER_TryOpenDriver32 [internal]
537 *
538 * Tries to load a 32 bit driver whose DLL's (module) name is lpFileName.
539 *
540 */
541static HDRVR DRIVER_TryOpenDriver32(LPCSTR lpFileName, LPARAM lParam, BOOL bCallFrom32)
542{
543 LPWINE_DRIVER lpDrv = NULL;
544 LPCSTR lpSFN;
545 HMODULE hModule;
546 DRIVERPROC lpProc;
547
548 dprintf(("'Entering DRIVER_TryOpenDriver32: %s', %08lX, %d);\n", lpFileName, lParam, bCallFrom32));
549
550 if (strlen(lpFileName) < 1)
551 return 0;
552
553 lpSFN = strrchr(lpFileName, '\\');
554 lpSFN = (lpSFN) ? (lpSFN + 1) : lpFileName;
555
556 if ((hModule = LoadLibraryA(lpFileName)) != 0) {
557 if ((lpProc = (DRIVERPROC)GetProcAddress(hModule, "DriverProc")) != NULL) {
558 lpDrv = DRIVER_RegisterDriver32(lpSFN, hModule, lpProc, lParam, bCallFrom32);
559 } else {
560 FreeLibrary(hModule);
561 lpDrv = 0;
562 dprintf(("DRIVER_TryOpenDriver32: No DriverProc found (line %d)\n",__LINE__));
563 }
564 } else {
565 dprintf(("DRIVER_TryOpenDriver32: Unable to load 32 bit module \"%s\" (line %d)\n", lpFileName,__LINE__));
566 }
567
568 dprintf(("(DRIVER_TryOpenDriver32) driver handle => %p\n", lpDrv));
569
570 return (HDRVR)lpDrv;
571}
572
573/**************************************************************************
574 * DRIVER_OpenDriverA [internal]
575 * (0,1,DRV_LOAD ,0 ,0)
576 * (0,1,DRV_ENABLE,0 ,0)
577 * (0,1,DRV_OPEN ,buf[256],0)
578 *
579 */
580static HDRVR DRIVER_OpenDriverA(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam)
581{
582 HDRVR hDriver = 0;
583 char drvName[128];
584
585 dprintf(("Entering DRIVER_OpenDriverA: lpDriverName: %s lpSectionName: %s\n",lpDriverName,lpSectionName));
586
587 if (lpSectionName == NULL) {
588 lstrcpynA(drvName, lpDriverName, sizeof(drvName));
589 hDriver = DRIVER_TryOpenDriver32(lpDriverName, lParam, TRUE);
590 if (!hDriver) {
591 if (GetPrivateProfileStringA("Drivers32", lpDriverName, "", drvName,
592 sizeof(drvName), "SYSTEM.INI")) {
593
594 hDriver = DRIVER_TryOpenDriver32(drvName, lParam, TRUE);
595 }
596 }
597 } else {/* of if (lpSectionName == NULL) */
598 //dprintf(("driver name %x '%s'\n",drvName,drvName));
599 drvName[0]=0;
600
601 if (GetPrivateProfileStringA(lpSectionName, lpDriverName, "", drvName,
602 sizeof(drvName)-1, "SYSTEM.INI")) {
603#if 0
604 dprintf(("driver name %x '%s'\n",drvName,drvName));
605#endif
606 hDriver = DRIVER_TryOpenDriver32(drvName, lParam, TRUE);
607 }/* GetPrivate... */
608 }
609 if (!hDriver)
610 dprintf(("OpenDriverA: Failed to open driver %s from section %s\n", lpDriverName, lpSectionName));
611
612 else
613 dprintf(("OpenDriverA success: Driver handle => %08x\n", hDriver));
614
615 return hDriver;
616}
617
618/**************************************************************************
619 * DRIVER_CloseDriver [internal]
620 *
621 *
622 */
623static BOOL DRIVER_CloseDriver(LPWINE_DRIVER lpDrv, DWORD lParam1, DWORD lParam2)
624{
625 if (lpDrv != NULL) {
626 SendDriverMessage((HDRVR)lpDrv, DRV_CLOSE, lParam1, lParam2);
627
628 if (DRIVER_RemoveFromList(lpDrv)) {
629 HeapFree(GetProcessHeap(), 0, lpDrv);
630 return TRUE;
631 }
632 }
633 dprintf(("Failed to close driver\n"));
634 return FALSE;
635}
636
637
638
639
640
641
642
643
644
645
646
647
Note: See TracBrowser for help on using the repository browser.