1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
4 * WINE Drivers functions
6 * Copyright 1994 Martin Ayotte
7 * Copyright 1998 Marcus Meissner
8 * Copyright 1999 Eric Pouech
19 #include "debugtools.h"
21 DEFAULT_DEBUG_CHANNEL(driver
)
23 static LPWINE_DRIVER lpDrvItemList
= NULL
;
26 * - LoadModule count and clean up is not handled correctly (it's not a problem as
27 * long as FreeLibrary is not working correctly)
28 * - msacm has some FIXME related to new code here...
31 /**************************************************************************
32 * LoadStartupDrivers [internal]
34 static void WINE_UNUSED
DRIVER_LoadStartupDrivers(void)
38 if (GetPrivateProfileStringA("drivers", NULL
, "", str
, sizeof(str
), "SYSTEM.INI") < 2) {
39 ERR("Can't find drivers section in system.ini\n");
44 for (ptr
= str
; lstrlenA(ptr
) != 0; ptr
+= lstrlenA(ptr
) + 1) {
45 TRACE("str='%s'\n", ptr
);
46 hDrv
= OpenDriver16(ptr
, "drivers", 0L);
47 TRACE("hDrv=%04x\n", hDrv
);
49 TRACE("end of list !\n");
53 /**************************************************************************
54 * DRIVER_GetNumberOfModuleRefs [internal]
56 * Returns the number of open drivers which share the same module.
58 static WORD
DRIVER_GetNumberOfModuleRefs(LPWINE_DRIVER lpNewDrv
)
61 DWORD type
= lpNewDrv
->dwFlags
& WINE_DI_TYPE_MASK
;
64 for (lpDrv
= lpDrvItemList
; lpDrv
; lpDrv
= lpDrv
->lpNextItem
) {
65 if ((lpDrv
->dwFlags
& WINE_DI_TYPE_MASK
) == type
) {
68 if (lpDrv
->d
.d16
.hModule
== lpNewDrv
->d
.d16
.hModule
)
72 if (lpDrv
->d
.d32
.hModule
== lpNewDrv
->d
.d32
.hModule
)
76 FIXME("Unsupported driver type: %ld\n", type
);
84 /**************************************************************************
85 * DRIVER_FindFromHDrvr16 [internal]
87 * From a hDrvr being 16 bits, returns the WINE internal structure.
89 static LPWINE_DRIVER
DRIVER_FindFromHDrvr16(HDRVR16 hDrvr
)
93 for (lpDrv
= lpDrvItemList
; lpDrv
; lpDrv
= lpDrv
->lpNextItem
) {
94 if (lpDrv
->hDriver16
== hDrvr
) {
101 /**************************************************************************
102 * DRIVER_FindFromHDrvr [internal]
104 * From a hDrvr (being 16 or 32 bits), returns the WINE internal structure.
106 static LPWINE_DRIVER
DRIVER_FindFromHDrvr(HDRVR hDrvr
)
108 if (!IsBadWritePtr((void*)hDrvr
, sizeof(WINE_DRIVER
)) &&
109 ((LPWINE_DRIVER
)hDrvr
)->dwMagic
== WINE_DI_MAGIC
) {
110 return (LPWINE_DRIVER
)hDrvr
;
112 return DRIVER_FindFromHDrvr16(hDrvr
);
115 /**************************************************************************
116 * DRIVER_GetType [internal]
118 * From a hDrvr (being 16 or 32 bits), returns the WINE internal structure.
120 int DRIVER_GetType(HDRVR hDrvr
)
122 LPWINE_DRIVER lpDrv
= DRIVER_FindFromHDrvr(hDrvr
);
124 return (lpDrv
) ? (lpDrv
->dwFlags
& WINE_DI_TYPE_MASK
) : 0;
127 /**************************************************************************
128 * DRIVER_MapMsg16To32 [internal]
130 * Map a 16 bit driver message to a 32 bit driver message.
131 * 1 : ok, some memory allocated, need to call DRIVER_UnMapMsg16To32
132 * 0 : ok, no memory allocated
133 * -1 : ko, unknown message
134 * -2 : ko, memory problem
136 static int DRIVER_MapMsg16To32(WORD wMsg
, DWORD
* lParam1
, DWORD
* lParam2
)
145 case DRV_QUERYCONFIGURE
:
147 case DRV_EXITSESSION
:
148 case DRV_EXITAPPLICATION
:
150 /* lParam1 and lParam2 are not used */
155 /* lParam1 is a NULL terminated string */
156 /* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
158 *lParam1
= (DWORD
)PTR_SEG_TO_LIN(*lParam1
);
159 if (*lParam2
&& wMsg
== DRV_OPEN
) {
160 LPMCI_OPEN_DRIVER_PARMS16 modp16
= PTR_SEG_TO_LIN(*lParam2
);
161 char* ptr
= HeapAlloc(SystemHeap
, 0, sizeof(LPMCI_OPEN_DRIVER_PARMS16
) + sizeof(MCI_OPEN_DRIVER_PARMSA
));
162 LPMCI_OPEN_DRIVER_PARMSA modp32
;
165 *(LPMCI_OPEN_DRIVER_PARMS16
*)ptr
= modp16
;
166 modp32
= (LPMCI_OPEN_DRIVER_PARMSA
)(ptr
+ sizeof(LPMCI_OPEN_DRIVER_PARMSA
));
168 modp32
->wDeviceID
= modp16
->wDeviceID
;
169 modp32
->lpstrParams
= PTR_SEG_TO_LIN(modp16
->lpstrParams
);
173 *lParam2
= (DWORD
)modp32
;
179 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO */
181 LPDRVCONFIGINFO dci32
= HeapAlloc(SystemHeap
, 0, sizeof(DRVCONFIGINFO
));
182 LPDRVCONFIGINFO16 dci16
= PTR_SEG_TO_LIN(*lParam2
);
185 dci32
->dwDCISize
= sizeof(DRVCONFIGINFO
);
186 dci32
->lpszDCISectionName
= HEAP_strdupAtoW(SystemHeap
, 0, PTR_SEG_TO_LIN(dci16
->lpszDCISectionName
));
187 dci32
->lpszDCIAliasName
= HEAP_strdupAtoW(SystemHeap
, 0, PTR_SEG_TO_LIN(dci16
->lpszDCIAliasName
));
188 if (dci32
->lpszDCISectionName
== NULL
|| dci32
->lpszDCIAliasName
== NULL
)
193 *lParam2
= (DWORD
)dci32
;
200 if (wMsg
>= 0x800 && wMsg
< 0x900) {
201 /* FIXME: another hack to handle MCI messages...
202 * should find a *NICE* way to integrate DRIVER_ and
203 * MCI_ mapping/unmapping functions
207 FIXME("Unknown message 0x%04x\n", wMsg
);
213 /**************************************************************************
214 * DRIVER_MapMsg16To32 [internal]
216 * UnMap a 16 bit driver message to a 32 bit driver message.
219 * -2 : ko, memory problem
221 static int DRIVER_UnMapMsg16To32(WORD wMsg
, DWORD lParam1
, DWORD lParam2
)
230 case DRV_QUERYCONFIGURE
:
232 case DRV_EXITSESSION
:
233 case DRV_EXITAPPLICATION
:
235 /* lParam1 and lParam2 are not used */
238 /* lParam1 is a NULL terminated string */
239 /* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
240 if (lParam2
&& wMsg
== DRV_OPEN
) {
241 LPMCI_OPEN_DRIVER_PARMSA modp32
= (LPMCI_OPEN_DRIVER_PARMSA
)lParam2
;
242 LPMCI_OPEN_DRIVER_PARMS16 modp16
= *(LPMCI_OPEN_DRIVER_PARMS16
*)(lParam2
- sizeof(LPMCI_OPEN_DRIVER_PARMSA
));
244 modp16
->wCustomCommandTable
= modp32
->wCustomCommandTable
;
245 modp16
->wType
= modp32
->wType
;
246 if (!HeapFree(SystemHeap
, 0, modp32
))
247 FIXME("bad free line=%d\n", __LINE__
);
253 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
255 LPDRVCONFIGINFO dci32
= (LPDRVCONFIGINFO
)lParam2
;
256 if (!HeapFree(SystemHeap
, 0, (LPVOID
)dci32
->lpszDCISectionName
))
257 FIXME("bad free line=%d\n", __LINE__
);
258 if (!HeapFree(SystemHeap
, 0, (LPVOID
)dci32
->lpszDCIAliasName
))
259 FIXME("bad free line=%d\n", __LINE__
);
260 if (!HeapFree(SystemHeap
, 0, dci32
))
261 FIXME("bad free line=%d\n", __LINE__
);
266 if (wMsg
>= 0x800 && wMsg
< 0x900) {
267 /* FIXME: another hack to handle MCI messages...
268 * should find a *NICE* way to integrate DRIVER_ and
269 * MCI_ mapping/unmapping functions
273 FIXME("Unknown message 0x%04x\n", wMsg
);
279 /**************************************************************************
280 * DRIVER_MapMsg32To16 [internal]
282 * Map a 32 bit driver message to a 16 bit driver message.
283 * 1 : ok, some memory allocated, need to call DRIVER_UnMapMsg32To16
284 * 0 : ok, no memory allocated
285 * -1 : ko, unknown message
286 * -2 : ko, memory problem
288 static int DRIVER_MapMsg32To16(WORD wMsg
, DWORD
* lParam1
, DWORD
* lParam2
)
297 case DRV_QUERYCONFIGURE
:
299 case DRV_EXITSESSION
:
300 case DRV_EXITAPPLICATION
:
302 /* lParam1 and lParam2 are not used */
307 /* lParam1 is a NULL terminated string */
308 /* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
310 LPSTR str
= SEGPTR_STRDUP((LPSTR
)*lParam1
);
312 *lParam1
= (LPARAM
)SEGPTR_GET(str
);
320 if (*lParam2
&& wMsg
== DRV_OPEN
) {
321 LPMCI_OPEN_DRIVER_PARMS16 modp16
;
322 char* ptr
= SEGPTR_ALLOC(sizeof(LPMCI_OPEN_DRIVER_PARMSA
) + sizeof(MCI_OPEN_DRIVER_PARMS16
));
323 LPMCI_OPEN_DRIVER_PARMSA modp32
= (LPMCI_OPEN_DRIVER_PARMSA
)(*lParam2
);
326 *(LPMCI_OPEN_DRIVER_PARMSA
*)ptr
= modp32
;
327 modp16
= (LPMCI_OPEN_DRIVER_PARMS16
)(ptr
+ sizeof(LPMCI_OPEN_DRIVER_PARMSA
));
329 modp16
->wDeviceID
= modp32
->wDeviceID
;
330 modp16
->lpstrParams
= PTR_SEG_TO_LIN(modp32
->lpstrParams
);
334 *lParam2
= (DWORD
)SEGPTR_GET(modp16
);
340 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO */
342 LPDRVCONFIGINFO16 dci16
= (LPDRVCONFIGINFO16
)SEGPTR_ALLOC(sizeof(DRVCONFIGINFO16
));
343 LPDRVCONFIGINFO dci32
= (LPDRVCONFIGINFO
)(*lParam2
);
348 dci16
->dwDCISize
= sizeof(DRVCONFIGINFO16
);
350 if ((str1
= HEAP_strdupWtoA(SystemHeap
, 0, dci32
->lpszDCISectionName
)) != NULL
&&
351 (str2
= SEGPTR_STRDUP(str1
)) != NULL
) {
352 dci16
->lpszDCISectionName
= (LPSTR
)SEGPTR_GET(str2
);
353 if (!HeapFree(SystemHeap
, 0, str1
))
354 FIXME("bad free line=%d\n", __LINE__
);
358 if ((str1
= HEAP_strdupWtoA(SystemHeap
, 0, dci32
->lpszDCIAliasName
)) != NULL
&&
359 (str2
= SEGPTR_STRDUP(str1
)) != NULL
) {
360 dci16
->lpszDCIAliasName
= (LPSTR
)SEGPTR_GET(str2
);
361 if (!HeapFree(SystemHeap
, 0, str1
))
362 FIXME("bad free line=%d\n", __LINE__
);
369 *lParam2
= (LPARAM
)SEGPTR_GET(dci16
);
376 if (wMsg
>= 0x800 && wMsg
< 0x900) {
377 /* FIXME: another hack to handle MCI messages...
378 * should find a *NICE* way to integrate DRIVER_ and
379 * MCI_ mapping/unmapping functions
383 FIXME("Unknown message 0x%04x\n", wMsg
);
389 /**************************************************************************
390 * DRIVER_UnMapMsg32To16 [internal]
392 * UnMap a 32 bit driver message to a 16 bit driver message.
395 * -2 : ko, memory problem
397 static int DRIVER_UnMapMsg32To16(WORD wMsg
, DWORD lParam1
, DWORD lParam2
)
406 case DRV_QUERYCONFIGURE
:
408 case DRV_EXITSESSION
:
409 case DRV_EXITAPPLICATION
:
411 /* lParam1 and lParam2 are not used */
414 /* lParam1 is a NULL terminated string, lParam2 is unknown => may lead to some problem */
415 /* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
416 if (lParam1
) if (!SEGPTR_FREE(PTR_SEG_TO_LIN(lParam1
)))
417 FIXME("bad free line=%d\n", __LINE__
);
419 if (lParam2
&& wMsg
== DRV_OPEN
) {
420 LPMCI_OPEN_DRIVER_PARMS16 modp16
= (LPMCI_OPEN_DRIVER_PARMS16
)PTR_SEG_TO_LIN(lParam2
);
421 LPMCI_OPEN_DRIVER_PARMSA modp32
= *(LPMCI_OPEN_DRIVER_PARMSA
*)((char*)modp16
- sizeof(LPMCI_OPEN_DRIVER_PARMSA
));
423 modp32
->wCustomCommandTable
= modp16
->wCustomCommandTable
;
424 modp32
->wType
= modp16
->wType
;
425 if (!SEGPTR_FREE((char*)modp16
- sizeof(LPMCI_OPEN_DRIVER_PARMSA
)))
426 FIXME("bad free line=%d\n", __LINE__
);
432 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
434 LPDRVCONFIGINFO16 dci16
= (LPDRVCONFIGINFO16
)PTR_SEG_TO_LIN(lParam2
);
436 if (!SEGPTR_FREE(PTR_SEG_TO_LIN(dci16
->lpszDCISectionName
)))
437 FIXME("bad free line=%d\n", __LINE__
);
438 if (!SEGPTR_FREE(PTR_SEG_TO_LIN(dci16
->lpszDCIAliasName
)))
439 FIXME("bad free line=%d\n", __LINE__
);
440 if (!SEGPTR_FREE(dci16
))
441 FIXME("bad free line=%d\n", __LINE__
);
446 if (wMsg
>= 0x800 && wMsg
< 0x900) {
447 /* FIXME: another hack to handle MCI messages...
448 * should find a *NICE* way to integrate DRIVER_ and
449 * MCI_ mapping/unmapping functions
453 FIXME("Unknown message 0x%04x\n", wMsg
);
459 /**************************************************************************
460 * SendDriverMessage [USER.251]
462 LRESULT WINAPI
SendDriverMessage16(HDRVR16 hDriver
, UINT16 msg
, LPARAM lParam1
,
469 TRACE("(%04x, %04X, %08lX, %08lX)\n", hDriver
, msg
, lParam1
, lParam2
);
471 lpDrv
= DRIVER_FindFromHDrvr16(hDriver
);
472 if (lpDrv
!= NULL
&& lpDrv
->hDriver16
== hDriver
) {
473 switch (lpDrv
->dwFlags
& WINE_DI_TYPE_MASK
) {
474 case WINE_DI_TYPE_16
:
475 TRACE("Before CallDriverProc proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
476 lpDrv
->d
.d16
.lpDrvProc
, lpDrv
->dwDriverID
, hDriver
, msg
, lParam1
, lParam2
);
477 retval
= Callbacks
->CallDriverProc(lpDrv
->d
.d16
.lpDrvProc
, lpDrv
->dwDriverID
, hDriver
,
478 msg
, lParam1
, lParam2
);
480 case WINE_DI_TYPE_32
:
481 mapRet
= DRIVER_MapMsg16To32(msg
, &lParam1
, &lParam2
);
483 TRACE("Before func32 call proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
484 lpDrv
->d
.d32
.lpDrvProc
, lpDrv
->dwDriverID
, (HDRVR
)lpDrv
, msg
, lParam1
, lParam2
);
485 retval
= lpDrv
->d
.d32
.lpDrvProc(lpDrv
->dwDriverID
, (HDRVR
)lpDrv
, msg
, lParam1
, lParam2
);
487 DRIVER_UnMapMsg16To32(msg
, lParam1
, lParam2
);
494 FIXME("Unknown driver type %08lx\n", lpDrv
->dwFlags
);
498 WARN("Bad driver handle %u\n", hDriver
);
501 TRACE("retval = %ld\n", retval
);
505 /**************************************************************************
506 * SendDriverMessage [WINMM.19]
508 LRESULT WINAPI
SendDriverMessage(HDRVR hDriver
, UINT msg
, LPARAM lParam1
,
515 TRACE("(%04x, %04X, %08lX, %08lX)\n", hDriver
, msg
, lParam1
, lParam2
);
517 lpDrv
= DRIVER_FindFromHDrvr(hDriver
);
520 switch (lpDrv
->dwFlags
& WINE_DI_TYPE_MASK
) {
521 case WINE_DI_TYPE_16
:
522 mapRet
= DRIVER_MapMsg32To16(msg
, &lParam1
, &lParam2
);
524 TRACE("Before CallDriverProc proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
525 lpDrv
->d
.d16
.lpDrvProc
, lpDrv
->dwDriverID
, lpDrv
->hDriver16
, msg
, lParam1
, lParam2
);
526 retval
= Callbacks
->CallDriverProc(lpDrv
->d
.d16
.lpDrvProc
, lpDrv
->dwDriverID
, lpDrv
->hDriver16
,
527 msg
, lParam1
, lParam2
);
529 DRIVER_UnMapMsg32To16(msg
, lParam1
, lParam2
);
535 case WINE_DI_TYPE_32
:
536 TRACE("Before func32 call proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
537 lpDrv
->d
.d32
.lpDrvProc
, lpDrv
->dwDriverID
, hDriver
, msg
, lParam1
, lParam2
);
538 retval
= lpDrv
->d
.d32
.lpDrvProc(lpDrv
->dwDriverID
, hDriver
, msg
, lParam1
, lParam2
);
541 FIXME("Unknown driver type %08lx\n", lpDrv
->dwFlags
);
545 WARN("Bad driver handle %u\n", hDriver
);
547 TRACE("retval = %ld\n", retval
);
552 /**************************************************************************
553 * DRIVER_RemoveFromList [internal]
555 * Generates all the logic to handle driver closure / deletion
556 * Removes a driver struct to the list of open drivers.
558 static BOOL
DRIVER_RemoveFromList(LPWINE_DRIVER lpDrv
)
560 lpDrv
->dwDriverID
= 0;
561 if (DRIVER_GetNumberOfModuleRefs(lpDrv
) == 1) {
562 SendDriverMessage((HDRVR
)lpDrv
, DRV_DISABLE
, 0L, 0L);
563 SendDriverMessage((HDRVR
)lpDrv
, DRV_FREE
, 0L, 0L);
566 if (lpDrv
->lpPrevItem
)
567 lpDrv
->lpPrevItem
->lpNextItem
= lpDrv
->lpNextItem
;
569 lpDrvItemList
= lpDrv
->lpNextItem
;
570 if (lpDrv
->lpNextItem
)
571 lpDrv
->lpNextItem
->lpPrevItem
= lpDrv
->lpPrevItem
;
576 /**************************************************************************
577 * DRIVER_AddToList [internal]
579 * Adds a driver struct to the list of open drivers.
580 * Generates all the logic to handle driver creation / open.
582 static BOOL
DRIVER_AddToList(LPWINE_DRIVER lpNewDrv
, LPARAM lParam
, BOOL bCallFrom32
)
584 lpNewDrv
->dwMagic
= WINE_DI_MAGIC
;
585 /* First driver to be loaded for this module, need to load correctly the module */
586 if (DRIVER_GetNumberOfModuleRefs(lpNewDrv
) == 0) {
587 if (SendDriverMessage((HDRVR
)lpNewDrv
, DRV_LOAD
, 0L, 0L) != DRV_SUCCESS
) {
588 TRACE("DRV_LOAD failed on driver 0x%08lx\n", (DWORD
)lpNewDrv
);
591 if (SendDriverMessage((HDRVR
)lpNewDrv
, DRV_ENABLE
, 0L, 0L) != DRV_SUCCESS
) {
592 TRACE("DRV_ENABLE failed on driver 0x%08lx\n", (DWORD
)lpNewDrv
);
597 lpNewDrv
->lpNextItem
= NULL
;
598 if (lpDrvItemList
== NULL
) {
599 lpDrvItemList
= lpNewDrv
;
600 lpNewDrv
->lpPrevItem
= NULL
;
602 LPWINE_DRIVER lpDrv
= lpDrvItemList
; /* find end of list */
603 while (lpDrv
->lpNextItem
!= NULL
)
604 lpDrv
= lpDrv
->lpNextItem
;
606 lpDrv
->lpNextItem
= lpNewDrv
;
607 lpNewDrv
->lpPrevItem
= lpDrv
;
610 /* Now just open a new instance of a driver on this module */
612 lpNewDrv
->dwDriverID
= SendDriverMessage((HDRVR
)lpNewDrv
, DRV_OPEN
, 0L, lParam
);
614 lpNewDrv
->dwDriverID
= SendDriverMessage16(lpNewDrv
->hDriver16
, DRV_OPEN
, 0L, lParam
);
616 if (lpNewDrv
->dwDriverID
== 0) {
617 TRACE("DRV_OPEN failed on driver 0x%08lx\n", (DWORD
)lpNewDrv
);
618 DRIVER_RemoveFromList(lpNewDrv
);
625 /**************************************************************************
626 * DRIVER_CreateDrvr16 [internal]
628 * Creates unique ID for 16 bit drivers.
630 static HDRVR16
DRIVER_CreateDrvr16()
632 static WORD DRIVER_hDrvr16Counter
= 0;
634 while (DRIVER_FindFromHDrvr16(++DRIVER_hDrvr16Counter
));
635 return DRIVER_hDrvr16Counter
;
638 /**************************************************************************
639 * DRIVER_CloseDriver [internal]
642 BOOL
DRIVER_CloseDriver(LPWINE_DRIVER lpDrv
, DWORD lParam1
, DWORD lParam2
)
645 SendDriverMessage((HDRVR
)lpDrv
, DRV_CLOSE
, lParam1
, lParam2
);
647 if (DRIVER_RemoveFromList(lpDrv
)) {
648 HeapFree(SystemHeap
, 0, lpDrv
);
652 WARN("Failed to close driver\n");
656 /**************************************************************************
657 * DRIVER_RegisterDriver16 [internal]
659 * Creates all the WINE internal representations for a 16 bit driver.
660 * The driver is also open by sending the correct messages.
662 LPWINE_DRIVER
DRIVER_RegisterDriver16(LPCSTR lpName
, HMODULE16 hModule
, DRIVERPROC16 lpProc
,
663 LPARAM lParam
, BOOL bCallFrom32
)
667 lpDrv
= HeapAlloc(SystemHeap
, 0, sizeof(WINE_DRIVER
));
669 lpDrv
->dwFlags
= WINE_DI_TYPE_16
;
670 lpDrv
->dwDriverID
= 0;
671 lpDrv
->hDriver16
= DRIVER_CreateDrvr16();
672 strncpy(lpDrv
->szAliasName
, lpName
, sizeof(lpDrv
->szAliasName
));
673 lpDrv
->d
.d16
.hModule
= hModule
;
674 lpDrv
->d
.d16
.lpDrvProc
= lpProc
;
676 if (!DRIVER_AddToList(lpDrv
, lParam
, bCallFrom32
)) {
677 HeapFree(SystemHeap
, 0, lpDrv
);
684 /**************************************************************************
685 * DRIVER_RegisterDriver32 [internal]
687 * Creates all the WINE internal representations for a 32 bit driver.
688 * The driver is also open by sending the correct messages.
690 LPWINE_DRIVER
DRIVER_RegisterDriver32(LPCSTR lpName
, HMODULE hModule
, DRIVERPROC lpProc
,
691 LPARAM lParam
, BOOL bCallFrom32
)
695 lpDrv
= HeapAlloc(SystemHeap
, 0, sizeof(WINE_DRIVER
));
697 lpDrv
->dwFlags
= WINE_DI_TYPE_32
;
698 lpDrv
->dwDriverID
= 0;
699 lpDrv
->hDriver16
= DRIVER_CreateDrvr16();
700 strncpy(lpDrv
->szAliasName
, lpName
, sizeof(lpDrv
->szAliasName
));
701 lpDrv
->d
.d32
.hModule
= hModule
;
702 lpDrv
->d
.d32
.lpDrvProc
= lpProc
;
704 if (!DRIVER_AddToList(lpDrv
, lParam
, bCallFrom32
)) {
705 HeapFree(SystemHeap
, 0, lpDrv
);
712 /**************************************************************************
713 * DRIVER_TryOpenDriver16 [internal]
715 * Tries to load a 16 bit driver whose DLL's (module) name is lpFileName.
717 static HDRVR16
DRIVER_TryOpenDriver16(LPCSTR lpFileName
, LPARAM lParam
, BOOL bCallFrom32
)
719 LPWINE_DRIVER lpDrv
= NULL
;
724 TRACE("('%s', %08lX, %d);\n", lpFileName
, lParam
, bCallFrom32
);
726 if (lstrlenA(lpFileName
) < 1)
729 lpSFN
= strrchr(lpFileName
, '\\');
730 lpSFN
= (lpSFN
) ? (lpSFN
+ 1) : lpFileName
;
732 if ((hModule
= LoadModule16(lpFileName
, (LPVOID
)-1)) >= 32) {
733 if ((lpProc
= (DRIVERPROC16
)WIN32_GetProcAddress16(hModule
, "DRIVERPROC")) != NULL
) {
734 lpDrv
= DRIVER_RegisterDriver16(lpSFN
, hModule
, lpProc
, lParam
, bCallFrom32
);
736 FreeLibrary16(hModule
);
737 TRACE("No DriverProc found\n");
741 TRACE("Unable to load 16 bit module (%s): %d\n", lpFileName
, hModule
);
743 return lpDrv
? lpDrv
->hDriver16
: 0;
746 /**************************************************************************
747 * DRIVER_TryOpenDriver32 [internal]
749 * Tries to load a 32 bit driver whose DLL's (module) name is lpFileName.
751 static HDRVR
DRIVER_TryOpenDriver32(LPCSTR lpFileName
, LPARAM lParam
, BOOL bCallFrom32
)
753 LPWINE_DRIVER lpDrv
= NULL
;
758 TRACE("('%s', %08lX, %d);\n", lpFileName
, lParam
, bCallFrom32
);
760 if (lstrlenA(lpFileName
) < 1)
763 lpSFN
= strrchr(lpFileName
, '\\');
764 lpSFN
= (lpSFN
) ? (lpSFN
+ 1) : lpFileName
;
766 if ((hModule
= LoadLibraryA(lpFileName
)) != 0) {
767 if ((lpProc
= GetProcAddress(hModule
, "DriverProc")) != NULL
) {
768 lpDrv
= DRIVER_RegisterDriver32(lpSFN
, hModule
, lpProc
, lParam
, bCallFrom32
);
770 FreeLibrary(hModule
);
772 TRACE("No DriverProc found\n");
775 TRACE("Unable to load 32 bit module \"%s\"\n", lpFileName
);
777 TRACE("=> %p\n", lpDrv
);
781 /**************************************************************************
782 * OpenDriver16 [USER.252]
784 HDRVR16 WINAPI
OpenDriver16(LPCSTR lpDriverName
, LPCSTR lpSectionName
, LPARAM lParam
)
789 TRACE("('%s', '%s', %08lX);\n", lpDriverName
, lpSectionName
, lParam
);
791 if (lpSectionName
== NULL
) {
792 hDriver
= DRIVER_TryOpenDriver16(lpDriverName
, lParam
, FALSE
);
794 hDriver
= DRIVER_TryOpenDriver32(lpDriverName
, lParam
, FALSE
);
797 /* in case hDriver is NULL, search in Drivers32 section */
798 lpSectionName
= "Drivers";
801 if (!hDriver
&& GetPrivateProfileStringA(lpSectionName
, lpDriverName
, "",
802 drvName
, sizeof(drvName
), "SYSTEM.INI") > 0) {
803 hDriver
= DRIVER_TryOpenDriver16(drvName
, lParam
, FALSE
);
808 /**************************************************************************
809 * OpenDriverA [WINMM.15]
810 * (0,1,DRV_LOAD ,0 ,0)
811 * (0,1,DRV_ENABLE,0 ,0)
812 * (0,1,DRV_OPEN ,buf[256],0)
814 HDRVR WINAPI
OpenDriverA(LPCSTR lpDriverName
, LPCSTR lpSectionName
, LPARAM lParam
)
819 TRACE("('%s', '%s', %08lX);\n", lpDriverName
, lpSectionName
, lParam
);
821 if (lpSectionName
== NULL
) {
822 strncpy(drvName
, lpDriverName
, sizeof(drvName
));
823 hDriver
= DRIVER_TryOpenDriver32(lpDriverName
, lParam
, TRUE
);
825 hDriver
= DRIVER_TryOpenDriver16(lpDriverName
, lParam
, TRUE
);
828 if (GetPrivateProfileStringA("Drivers32", lpDriverName
, "", drvName
,
829 sizeof(drvName
), "SYSTEM.INI")) {
830 hDriver
= DRIVER_TryOpenDriver32(drvName
, lParam
, TRUE
);
835 if (GetPrivateProfileStringA("Drivers", lpDriverName
, "", drvName
,
836 sizeof(drvName
), "SYSTEM.INI")) {
837 hDriver
= DRIVER_TryOpenDriver16(drvName
, lParam
, TRUE
);
842 if (GetPrivateProfileStringA(lpSectionName
, lpDriverName
, "", drvName
,
843 sizeof(drvName
), "SYSTEM.INI")) {
844 hDriver
= DRIVER_TryOpenDriver32(drvName
, lParam
, TRUE
);
846 hDriver
= DRIVER_TryOpenDriver16(drvName
, lParam
, TRUE
);
850 TRACE("retval='%08x'\n", hDriver
);
854 /**************************************************************************
855 * OpenDriverW [WINMM.15]
857 HDRVR WINAPI
OpenDriverW(LPCWSTR lpDriverName
, LPCWSTR lpSectionName
, LPARAM lParam
)
859 LPSTR dn
= HEAP_strdupWtoA(GetProcessHeap(), 0, lpDriverName
);
860 LPSTR sn
= HEAP_strdupWtoA(GetProcessHeap(), 0, lpSectionName
);
861 HDRVR ret
= OpenDriverA(dn
, sn
, lParam
);
863 if (dn
) HeapFree(GetProcessHeap(), 0, dn
);
864 if (sn
) HeapFree(GetProcessHeap(), 0, sn
);
868 /**************************************************************************
869 * CloseDriver16 [USER.253]
871 LRESULT WINAPI
CloseDriver16(HDRVR16 hDrvr
, LPARAM lParam1
, LPARAM lParam2
)
873 TRACE("(%04x, %08lX, %08lX);\n", hDrvr
, lParam1
, lParam2
);
875 return DRIVER_CloseDriver(DRIVER_FindFromHDrvr16(hDrvr
), lParam1
, lParam2
);
878 /**************************************************************************
879 * CloseDriver [WINMM.4]
881 LRESULT WINAPI
CloseDriver(HDRVR hDrvr
, LPARAM lParam1
, LPARAM lParam2
)
883 TRACE("(%04x, %08lX, %08lX);\n", hDrvr
, lParam1
, lParam2
);
885 return DRIVER_CloseDriver(DRIVER_FindFromHDrvr(hDrvr
), lParam1
, lParam2
);
888 /**************************************************************************
889 * GetDriverModuleHandle [USER.254]
891 HMODULE16 WINAPI
GetDriverModuleHandle16(HDRVR16 hDrvr
)
894 HMODULE16 hModule
= 0;
896 TRACE("(%04x);\n", hDrvr
);
898 lpDrv
= DRIVER_FindFromHDrvr16(hDrvr
);
899 if (lpDrv
!= NULL
&& lpDrv
->hDriver16
== hDrvr
&&
900 (lpDrv
->dwFlags
& WINE_DI_TYPE_MASK
) == WINE_DI_TYPE_16
) {
901 hModule
= lpDrv
->d
.d16
.hModule
;
903 TRACE("=> %d\n", hModule
);
907 /**************************************************************************
908 * GetDriverFlags [WINMM.13]
910 DWORD WINAPI
GetDriverFlags(HDRVR hDrvr
)
912 FIXME("(%04x); stub!\n", hDrvr
);
916 /**************************************************************************
917 * GetDriverModuleHandle [WINMM.14]
919 HMODULE WINAPI
GetDriverModuleHandle(HDRVR hDrvr
)
924 TRACE("(%04x);\n", hDrvr
);
926 lpDrv
= DRIVER_FindFromHDrvr(hDrvr
);
927 if (lpDrv
!= NULL
&& (lpDrv
->dwFlags
& WINE_DI_TYPE_MASK
) == WINE_DI_TYPE_32
) {
928 hModule
= lpDrv
->d
.d32
.hModule
;
930 TRACE("=> %d\n", hModule
);
934 /**************************************************************************
935 * DefDriverProc16 [USER.255]
937 LRESULT WINAPI
DefDriverProc16(DWORD dwDevID
, HDRVR16 hDriv
, UINT16 wMsg
,
938 LPARAM lParam1
, LPARAM lParam2
)
940 TRACE("devID=0x%08lx hDrv=0x%04x wMsg=%04x lP1=0x%08lx lP2=0x%08lx\n",
941 dwDevID
, hDriv
, wMsg
, lParam1
, lParam2
);
951 case DRV_QUERYCONFIGURE
:
954 MessageBoxA(0, "Driver isn't configurable !", "Wine Driver", MB_OK
);
964 /**************************************************************************
965 * GetDriverInfo [USER.256]
967 BOOL16 WINAPI
GetDriverInfo16(HDRVR16 hDrvr
, LPDRIVERINFOSTRUCT16 lpDrvInfo
)
972 TRACE("(%04x, %p);\n", hDrvr
, lpDrvInfo
);
974 if (lpDrvInfo
== NULL
|| lpDrvInfo
->length
!= sizeof(DRIVERINFOSTRUCT16
))
977 lpDrv
= DRIVER_FindFromHDrvr16(hDrvr
);
978 if (lpDrv
!= NULL
&& lpDrv
->hDriver16
== hDrvr
&&
979 (lpDrv
->dwFlags
& WINE_DI_TYPE_MASK
) == WINE_DI_TYPE_16
) {
980 lpDrvInfo
->hDriver
= lpDrv
->hDriver16
;
981 lpDrvInfo
->hModule
= lpDrv
->d
.d16
.hModule
;
982 strncpy(lpDrvInfo
->szAliasName
, lpDrv
->szAliasName
, sizeof(lpDrvInfo
->szAliasName
));
989 /**************************************************************************
990 * GetNextDriver [USER.257]
992 HDRVR16 WINAPI
GetNextDriver16(HDRVR16 hDrvr
, DWORD dwFlags
)
997 TRACE("(%04x, %08lX);\n", hDrvr
, dwFlags
);
1000 if (lpDrvItemList
== NULL
) {
1001 FIXME("drivers list empty !\n");
1002 /* FIXME: code was using DRIVER_LoadStartupDrivers(); before ?
1003 * I (EPP) don't quite understand this
1005 if (lpDrvItemList
== NULL
)
1008 lpDrv
= lpDrvItemList
;
1009 if (dwFlags
& GND_REVERSE
) {
1010 while (lpDrv
->lpNextItem
)
1011 lpDrv
= lpDrv
->lpNextItem
;
1014 lpDrv
= DRIVER_FindFromHDrvr16(hDrvr
);
1015 if (lpDrv
!= NULL
) {
1016 if (dwFlags
& GND_REVERSE
) {
1017 lpDrv
= (lpDrv
->lpPrevItem
) ? lpDrv
->lpPrevItem
: NULL
;
1019 lpDrv
= (lpDrv
->lpNextItem
) ? lpDrv
->lpNextItem
: NULL
;
1024 hRetDrv
= (lpDrv
) ? lpDrv
->hDriver16
: (HDRVR16
)0;
1025 TRACE("return %04x !\n", hRetDrv
);